Lines Matching +full:dma +full:- +full:safe +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0-only
10 * See Documentation/userspace-api/dcdbas.rst for more information.
12 * Copyright (C) 1995-2006 Dell Inc.
17 #include <linux/dma-mapping.h>
39 #define DRIVER_VERSION "5.6.0-3.4"
57 smi_buffer->virt = dma_alloc_coherent(&dcdbas_pdev->dev, size, in dcdbas_smi_alloc()
58 &smi_buffer->dma, GFP_KERNEL); in dcdbas_smi_alloc()
59 if (!smi_buffer->virt) { in dcdbas_smi_alloc()
60 dev_dbg(&dcdbas_pdev->dev, in dcdbas_smi_alloc()
63 return -ENOMEM; in dcdbas_smi_alloc()
65 smi_buffer->size = size; in dcdbas_smi_alloc()
67 dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n", in dcdbas_smi_alloc()
68 __func__, (u32)smi_buffer->dma, smi_buffer->size); in dcdbas_smi_alloc()
76 if (!smi_buffer->virt) in dcdbas_smi_free()
79 dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n", in dcdbas_smi_free()
80 __func__, (u32)smi_buffer->dma, smi_buffer->size); in dcdbas_smi_free()
81 dma_free_coherent(&dcdbas_pdev->dev, smi_buffer->size, in dcdbas_smi_free()
82 smi_buffer->virt, smi_buffer->dma); in dcdbas_smi_free()
83 smi_buffer->virt = NULL; in dcdbas_smi_free()
84 smi_buffer->dma = 0; in dcdbas_smi_free()
85 smi_buffer->size = 0; in dcdbas_smi_free()
112 return -EINVAL; in smi_data_buf_realloc()
136 return sysfs_emit(buf, "%x\n", (u32)smi_buf.dma); in smi_data_buf_phys_addr_show()
185 return -EINVAL; in smi_data_write()
259 dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n", in raise_smi()
261 return -EBUSY; in raise_smi()
270 : "a" (smi_cmd->command_code), in raise_smi()
271 "d" (smi_cmd->command_address), in raise_smi()
272 "b" (smi_cmd->ebx), in raise_smi()
273 "c" (smi_cmd->ecx) in raise_smi()
288 if (smi_cmd->magic != SMI_CMD_MAGIC) { in dcdbas_smi_request()
289 dev_info(&dcdbas_pdev->dev, "%s: invalid magic value\n", in dcdbas_smi_request()
291 return -EBADR; in dcdbas_smi_request()
325 ret = -ENODEV; in smi_request_store()
345 * will be from memremap() of a non-memory address if WSMT in smi_request_store()
350 smi_cmd->ebx = (u32)smi_buf.dma + in smi_request_store()
361 ret = -EINVAL; in smi_request_store()
385 apm_cmd->status = ESM_STATUS_CMD_UNSUCCESSFUL; in host_control_smi()
391 data = (u8 *)&smi_buf.dma; in host_control_smi()
401 /* first set status to -1 as called by spec */ in host_control_smi()
412 num_ticks--; in host_control_smi()
414 return -ETIME; in host_control_smi()
422 data = (u8 *)&smi_buf.dma; in host_control_smi()
445 while (apm_cmd->status == ESM_STATUS_CMD_UNSUCCESSFUL) { in host_control_smi()
446 num_ticks--; in host_control_smi()
448 return -ETIME; in host_control_smi()
453 dev_dbg(&dcdbas_pdev->dev, "%s: invalid SMI type %u\n", in host_control_smi()
455 return -ENOSYS; in host_control_smi()
466 * host control action to perform on shutdown. It is safe to
482 dev_dbg(&dcdbas_pdev->dev, "%s: no SMI buffer\n", __func__); in dcdbas_host_control()
487 dev_dbg(&dcdbas_pdev->dev, "%s: SMI buffer too small\n", in dcdbas_host_control()
496 apm_cmd->command = ESM_APM_POWER_CYCLE; in dcdbas_host_control()
497 apm_cmd->reserved = 0; in dcdbas_host_control()
498 *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 0; in dcdbas_host_control()
501 apm_cmd->command = ESM_APM_POWER_CYCLE; in dcdbas_host_control()
502 apm_cmd->reserved = 0; in dcdbas_host_control()
503 *((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 20; in dcdbas_host_control()
524 if (strncmp(eps->smm_comm_buff_anchor, SMM_EPS_SIG, 4) != 0) in check_eps_table()
527 if (checksum(addr, eps->length) != 0) in check_eps_table()
547 if (!(wsmt->protection_flags & ACPI_WSMT_FIXED_COMM_BUFFERS) || in dcdbas_check_wsmt()
548 !(wsmt->protection_flags & ACPI_WSMT_COMM_BUFFER_NESTED_PTR_PROTECTION)) in dcdbas_check_wsmt()
558 if (sscanf(dev->name, "30[%16llx;%8llx]", &bios_buf_paddr, in dcdbas_check_wsmt()
564 addr < (u8 *)__va(0x100000 - sizeof(struct smm_eps_table)); in dcdbas_check_wsmt()
572 dev_dbg(&dcdbas_pdev->dev, "found WSMT, but no firmware buffer found\n"); in dcdbas_check_wsmt()
573 return -ENODEV; in dcdbas_check_wsmt()
575 bios_buf_paddr = eps->smm_comm_buff_addr; in dcdbas_check_wsmt()
576 remap_size = eps->num_of_4k_pages * PAGE_SIZE; in dcdbas_check_wsmt()
580 * Get physical address of buffer and map to virtual address. in dcdbas_check_wsmt()
584 dev_warn(&dcdbas_pdev->dev, "found WSMT, but buffer address is above 4GB\n"); in dcdbas_check_wsmt()
585 return -EINVAL; in dcdbas_check_wsmt()
596 dev_warn(&dcdbas_pdev->dev, "found WSMT, but failed to map buffer\n"); in dcdbas_check_wsmt()
597 return -ENOMEM; in dcdbas_check_wsmt()
601 smi_buf.dma = bios_buf_paddr + 8; in dcdbas_check_wsmt()
603 smi_buf.size = remap_size - 8; in dcdbas_check_wsmt()
606 dev_info(&dcdbas_pdev->dev, in dcdbas_check_wsmt()
607 "WSMT found, using firmware-provided SMI buffer.\n"); in dcdbas_check_wsmt()
683 * BIOS SMI calls require buffer addresses be in 32-bit address space. in dcdbas_probe()
684 * This is done by setting the DMA mask below. in dcdbas_probe()
686 error = dma_set_coherent_mask(&dcdbas_pdev->dev, DMA_BIT_MASK(32)); in dcdbas_probe()
690 error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group); in dcdbas_probe()
696 dev_info(&dev->dev, "%s (version %s)\n", in dcdbas_probe()
705 sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group); in dcdbas_remove()