| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | | - * |
|---|
| 3 | + * Copyright (c) 2003-2020, Intel Corporation. All rights reserved. |
|---|
| 3 | 4 | * Intel Management Engine Interface (Intel MEI) Linux driver |
|---|
| 4 | | - * Copyright (c) 2003-2012, Intel Corporation. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 8 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | 5 | */ |
|---|
| 16 | | - |
|---|
| 17 | 6 | #include <linux/export.h> |
|---|
| 18 | 7 | #include <linux/sched.h> |
|---|
| 19 | 8 | #include <linux/wait.h> |
|---|
| .. | .. |
|---|
| 65 | 54 | MEI_HBM_STATE(IDLE); |
|---|
| 66 | 55 | MEI_HBM_STATE(STARTING); |
|---|
| 67 | 56 | MEI_HBM_STATE(STARTED); |
|---|
| 57 | + MEI_HBM_STATE(DR_SETUP); |
|---|
| 68 | 58 | MEI_HBM_STATE(ENUM_CLIENTS); |
|---|
| 69 | 59 | MEI_HBM_STATE(CLIENT_PROPERTIES); |
|---|
| 70 | 60 | MEI_HBM_STATE(STOPPED); |
|---|
| .. | .. |
|---|
| 135 | 125 | /** |
|---|
| 136 | 126 | * mei_hbm_hdr - construct hbm header |
|---|
| 137 | 127 | * |
|---|
| 138 | | - * @hdr: hbm header |
|---|
| 128 | + * @mei_hdr: hbm header |
|---|
| 139 | 129 | * @length: payload length |
|---|
| 140 | 130 | */ |
|---|
| 141 | 131 | |
|---|
| 142 | | -static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) |
|---|
| 132 | +static inline void mei_hbm_hdr(struct mei_msg_hdr *mei_hdr, size_t length) |
|---|
| 143 | 133 | { |
|---|
| 144 | | - hdr->host_addr = 0; |
|---|
| 145 | | - hdr->me_addr = 0; |
|---|
| 146 | | - hdr->length = length; |
|---|
| 147 | | - hdr->msg_complete = 1; |
|---|
| 148 | | - hdr->dma_ring = 0; |
|---|
| 149 | | - hdr->reserved = 0; |
|---|
| 150 | | - hdr->internal = 0; |
|---|
| 134 | + memset(mei_hdr, 0, sizeof(*mei_hdr)); |
|---|
| 135 | + mei_hdr->length = length; |
|---|
| 136 | + mei_hdr->msg_complete = 1; |
|---|
| 151 | 137 | } |
|---|
| 152 | 138 | |
|---|
| 153 | 139 | /** |
|---|
| .. | .. |
|---|
| 267 | 253 | int mei_hbm_start_req(struct mei_device *dev) |
|---|
| 268 | 254 | { |
|---|
| 269 | 255 | struct mei_msg_hdr mei_hdr; |
|---|
| 270 | | - struct hbm_host_version_request start_req; |
|---|
| 271 | | - const size_t len = sizeof(struct hbm_host_version_request); |
|---|
| 256 | + struct hbm_host_version_request req; |
|---|
| 272 | 257 | int ret; |
|---|
| 273 | 258 | |
|---|
| 274 | 259 | mei_hbm_reset(dev); |
|---|
| 275 | 260 | |
|---|
| 276 | | - mei_hbm_hdr(&mei_hdr, len); |
|---|
| 261 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 277 | 262 | |
|---|
| 278 | 263 | /* host start message */ |
|---|
| 279 | | - memset(&start_req, 0, len); |
|---|
| 280 | | - start_req.hbm_cmd = HOST_START_REQ_CMD; |
|---|
| 281 | | - start_req.host_version.major_version = HBM_MAJOR_VERSION; |
|---|
| 282 | | - start_req.host_version.minor_version = HBM_MINOR_VERSION; |
|---|
| 264 | + memset(&req, 0, sizeof(req)); |
|---|
| 265 | + req.hbm_cmd = HOST_START_REQ_CMD; |
|---|
| 266 | + req.host_version.major_version = HBM_MAJOR_VERSION; |
|---|
| 267 | + req.host_version.minor_version = HBM_MINOR_VERSION; |
|---|
| 283 | 268 | |
|---|
| 284 | 269 | dev->hbm_state = MEI_HBM_IDLE; |
|---|
| 285 | | - ret = mei_hbm_write_message(dev, &mei_hdr, &start_req); |
|---|
| 270 | + ret = mei_hbm_write_message(dev, &mei_hdr, &req); |
|---|
| 286 | 271 | if (ret) { |
|---|
| 287 | 272 | dev_err(dev->dev, "version message write failed: ret = %d\n", |
|---|
| 288 | 273 | ret); |
|---|
| .. | .. |
|---|
| 290 | 275 | } |
|---|
| 291 | 276 | |
|---|
| 292 | 277 | dev->hbm_state = MEI_HBM_STARTING; |
|---|
| 278 | + dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; |
|---|
| 279 | + mei_schedule_stall_timer(dev); |
|---|
| 280 | + return 0; |
|---|
| 281 | +} |
|---|
| 282 | + |
|---|
| 283 | +/** |
|---|
| 284 | + * mei_hbm_dma_setup_req() - setup DMA request |
|---|
| 285 | + * @dev: the device structure |
|---|
| 286 | + * |
|---|
| 287 | + * Return: 0 on success and < 0 on failure |
|---|
| 288 | + */ |
|---|
| 289 | +static int mei_hbm_dma_setup_req(struct mei_device *dev) |
|---|
| 290 | +{ |
|---|
| 291 | + struct mei_msg_hdr mei_hdr; |
|---|
| 292 | + struct hbm_dma_setup_request req; |
|---|
| 293 | + unsigned int i; |
|---|
| 294 | + int ret; |
|---|
| 295 | + |
|---|
| 296 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 297 | + |
|---|
| 298 | + memset(&req, 0, sizeof(req)); |
|---|
| 299 | + req.hbm_cmd = MEI_HBM_DMA_SETUP_REQ_CMD; |
|---|
| 300 | + for (i = 0; i < DMA_DSCR_NUM; i++) { |
|---|
| 301 | + phys_addr_t paddr; |
|---|
| 302 | + |
|---|
| 303 | + paddr = dev->dr_dscr[i].daddr; |
|---|
| 304 | + req.dma_dscr[i].addr_hi = upper_32_bits(paddr); |
|---|
| 305 | + req.dma_dscr[i].addr_lo = lower_32_bits(paddr); |
|---|
| 306 | + req.dma_dscr[i].size = dev->dr_dscr[i].size; |
|---|
| 307 | + } |
|---|
| 308 | + |
|---|
| 309 | + mei_dma_ring_reset(dev); |
|---|
| 310 | + |
|---|
| 311 | + ret = mei_hbm_write_message(dev, &mei_hdr, &req); |
|---|
| 312 | + if (ret) { |
|---|
| 313 | + dev_err(dev->dev, "dma setup request write failed: ret = %d.\n", |
|---|
| 314 | + ret); |
|---|
| 315 | + return ret; |
|---|
| 316 | + } |
|---|
| 317 | + |
|---|
| 318 | + dev->hbm_state = MEI_HBM_DR_SETUP; |
|---|
| 319 | + dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; |
|---|
| 320 | + mei_schedule_stall_timer(dev); |
|---|
| 321 | + return 0; |
|---|
| 322 | +} |
|---|
| 323 | + |
|---|
| 324 | +/** |
|---|
| 325 | + * mei_hbm_capabilities_req - request capabilities |
|---|
| 326 | + * |
|---|
| 327 | + * @dev: the device structure |
|---|
| 328 | + * |
|---|
| 329 | + * Return: 0 on success and < 0 on failure |
|---|
| 330 | + */ |
|---|
| 331 | +static int mei_hbm_capabilities_req(struct mei_device *dev) |
|---|
| 332 | +{ |
|---|
| 333 | + struct mei_msg_hdr mei_hdr; |
|---|
| 334 | + struct hbm_capability_request req; |
|---|
| 335 | + int ret; |
|---|
| 336 | + |
|---|
| 337 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 338 | + |
|---|
| 339 | + memset(&req, 0, sizeof(req)); |
|---|
| 340 | + req.hbm_cmd = MEI_HBM_CAPABILITIES_REQ_CMD; |
|---|
| 341 | + if (dev->hbm_f_vt_supported) |
|---|
| 342 | + req.capability_requested[0] = HBM_CAP_VT; |
|---|
| 343 | + |
|---|
| 344 | + ret = mei_hbm_write_message(dev, &mei_hdr, &req); |
|---|
| 345 | + if (ret) { |
|---|
| 346 | + dev_err(dev->dev, |
|---|
| 347 | + "capabilities request write failed: ret = %d.\n", ret); |
|---|
| 348 | + return ret; |
|---|
| 349 | + } |
|---|
| 350 | + |
|---|
| 351 | + dev->hbm_state = MEI_HBM_CAP_SETUP; |
|---|
| 293 | 352 | dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; |
|---|
| 294 | 353 | mei_schedule_stall_timer(dev); |
|---|
| 295 | 354 | return 0; |
|---|
| .. | .. |
|---|
| 305 | 364 | static int mei_hbm_enum_clients_req(struct mei_device *dev) |
|---|
| 306 | 365 | { |
|---|
| 307 | 366 | struct mei_msg_hdr mei_hdr; |
|---|
| 308 | | - struct hbm_host_enum_request enum_req; |
|---|
| 309 | | - const size_t len = sizeof(struct hbm_host_enum_request); |
|---|
| 367 | + struct hbm_host_enum_request req; |
|---|
| 310 | 368 | int ret; |
|---|
| 311 | 369 | |
|---|
| 312 | 370 | /* enumerate clients */ |
|---|
| 313 | | - mei_hbm_hdr(&mei_hdr, len); |
|---|
| 371 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 314 | 372 | |
|---|
| 315 | | - memset(&enum_req, 0, len); |
|---|
| 316 | | - enum_req.hbm_cmd = HOST_ENUM_REQ_CMD; |
|---|
| 317 | | - enum_req.flags |= dev->hbm_f_dc_supported ? |
|---|
| 318 | | - MEI_HBM_ENUM_F_ALLOW_ADD : 0; |
|---|
| 319 | | - enum_req.flags |= dev->hbm_f_ie_supported ? |
|---|
| 373 | + memset(&req, 0, sizeof(req)); |
|---|
| 374 | + req.hbm_cmd = HOST_ENUM_REQ_CMD; |
|---|
| 375 | + req.flags |= dev->hbm_f_dc_supported ? MEI_HBM_ENUM_F_ALLOW_ADD : 0; |
|---|
| 376 | + req.flags |= dev->hbm_f_ie_supported ? |
|---|
| 320 | 377 | MEI_HBM_ENUM_F_IMMEDIATE_ENUM : 0; |
|---|
| 321 | 378 | |
|---|
| 322 | | - ret = mei_hbm_write_message(dev, &mei_hdr, &enum_req); |
|---|
| 379 | + ret = mei_hbm_write_message(dev, &mei_hdr, &req); |
|---|
| 323 | 380 | if (ret) { |
|---|
| 324 | 381 | dev_err(dev->dev, "enumeration request write failed: ret = %d.\n", |
|---|
| 325 | 382 | ret); |
|---|
| .. | .. |
|---|
| 348 | 405 | |
|---|
| 349 | 406 | mei_me_cl_rm_by_uuid(dev, uuid); |
|---|
| 350 | 407 | |
|---|
| 351 | | - me_cl = kzalloc(sizeof(struct mei_me_client), GFP_KERNEL); |
|---|
| 408 | + me_cl = kzalloc(sizeof(*me_cl), GFP_KERNEL); |
|---|
| 352 | 409 | if (!me_cl) |
|---|
| 353 | 410 | return -ENOMEM; |
|---|
| 354 | 411 | |
|---|
| .. | .. |
|---|
| 376 | 433 | { |
|---|
| 377 | 434 | struct mei_msg_hdr mei_hdr; |
|---|
| 378 | 435 | struct hbm_add_client_response resp; |
|---|
| 379 | | - const size_t len = sizeof(struct hbm_add_client_response); |
|---|
| 380 | 436 | int ret; |
|---|
| 381 | 437 | |
|---|
| 382 | 438 | dev_dbg(dev->dev, "adding client response\n"); |
|---|
| 383 | 439 | |
|---|
| 384 | | - mei_hbm_hdr(&mei_hdr, len); |
|---|
| 440 | + mei_hbm_hdr(&mei_hdr, sizeof(resp)); |
|---|
| 385 | 441 | |
|---|
| 386 | | - memset(&resp, 0, sizeof(struct hbm_add_client_response)); |
|---|
| 442 | + memset(&resp, 0, sizeof(resp)); |
|---|
| 387 | 443 | resp.hbm_cmd = MEI_HBM_ADD_CLIENT_RES_CMD; |
|---|
| 388 | 444 | resp.me_addr = addr; |
|---|
| 389 | 445 | resp.status = status; |
|---|
| .. | .. |
|---|
| 437 | 493 | |
|---|
| 438 | 494 | struct mei_msg_hdr mei_hdr; |
|---|
| 439 | 495 | struct hbm_notification_request req; |
|---|
| 440 | | - const size_t len = sizeof(struct hbm_notification_request); |
|---|
| 441 | 496 | int ret; |
|---|
| 442 | 497 | |
|---|
| 443 | | - mei_hbm_hdr(&mei_hdr, len); |
|---|
| 444 | | - mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, len); |
|---|
| 498 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 499 | + mei_hbm_cl_hdr(cl, MEI_HBM_NOTIFY_REQ_CMD, &req, sizeof(req)); |
|---|
| 445 | 500 | |
|---|
| 446 | 501 | req.start = start; |
|---|
| 447 | 502 | |
|---|
| .. | .. |
|---|
| 548 | 603 | static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) |
|---|
| 549 | 604 | { |
|---|
| 550 | 605 | struct mei_msg_hdr mei_hdr; |
|---|
| 551 | | - struct hbm_props_request prop_req; |
|---|
| 552 | | - const size_t len = sizeof(struct hbm_props_request); |
|---|
| 606 | + struct hbm_props_request req; |
|---|
| 553 | 607 | unsigned long addr; |
|---|
| 554 | 608 | int ret; |
|---|
| 555 | 609 | |
|---|
| .. | .. |
|---|
| 559 | 613 | if (addr == MEI_CLIENTS_MAX) { |
|---|
| 560 | 614 | dev->hbm_state = MEI_HBM_STARTED; |
|---|
| 561 | 615 | mei_host_client_init(dev); |
|---|
| 562 | | - |
|---|
| 563 | 616 | return 0; |
|---|
| 564 | 617 | } |
|---|
| 565 | 618 | |
|---|
| 566 | | - mei_hbm_hdr(&mei_hdr, len); |
|---|
| 619 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 567 | 620 | |
|---|
| 568 | | - memset(&prop_req, 0, sizeof(struct hbm_props_request)); |
|---|
| 621 | + memset(&req, 0, sizeof(req)); |
|---|
| 569 | 622 | |
|---|
| 570 | | - prop_req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; |
|---|
| 571 | | - prop_req.me_addr = addr; |
|---|
| 623 | + req.hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; |
|---|
| 624 | + req.me_addr = addr; |
|---|
| 572 | 625 | |
|---|
| 573 | | - ret = mei_hbm_write_message(dev, &mei_hdr, &prop_req); |
|---|
| 626 | + ret = mei_hbm_write_message(dev, &mei_hdr, &req); |
|---|
| 574 | 627 | if (ret) { |
|---|
| 575 | 628 | dev_err(dev->dev, "properties request write failed: ret = %d\n", |
|---|
| 576 | 629 | ret); |
|---|
| .. | .. |
|---|
| 596 | 649 | { |
|---|
| 597 | 650 | struct mei_msg_hdr mei_hdr; |
|---|
| 598 | 651 | struct hbm_power_gate req; |
|---|
| 599 | | - const size_t len = sizeof(struct hbm_power_gate); |
|---|
| 600 | 652 | int ret; |
|---|
| 601 | 653 | |
|---|
| 602 | 654 | if (!dev->hbm_f_pg_supported) |
|---|
| 603 | 655 | return -EOPNOTSUPP; |
|---|
| 604 | 656 | |
|---|
| 605 | | - mei_hbm_hdr(&mei_hdr, len); |
|---|
| 657 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 606 | 658 | |
|---|
| 607 | | - memset(&req, 0, len); |
|---|
| 659 | + memset(&req, 0, sizeof(req)); |
|---|
| 608 | 660 | req.hbm_cmd = pg_cmd; |
|---|
| 609 | 661 | |
|---|
| 610 | 662 | ret = mei_hbm_write_message(dev, &mei_hdr, &req); |
|---|
| .. | .. |
|---|
| 625 | 677 | { |
|---|
| 626 | 678 | struct mei_msg_hdr mei_hdr; |
|---|
| 627 | 679 | struct hbm_host_stop_request req; |
|---|
| 628 | | - const size_t len = sizeof(struct hbm_host_stop_request); |
|---|
| 629 | 680 | |
|---|
| 630 | | - mei_hbm_hdr(&mei_hdr, len); |
|---|
| 681 | + mei_hbm_hdr(&mei_hdr, sizeof(req)); |
|---|
| 631 | 682 | |
|---|
| 632 | | - memset(&req, 0, len); |
|---|
| 683 | + memset(&req, 0, sizeof(req)); |
|---|
| 633 | 684 | req.hbm_cmd = HOST_STOP_REQ_CMD; |
|---|
| 634 | 685 | req.reason = DRIVER_STOP_REQUEST; |
|---|
| 635 | 686 | |
|---|
| .. | .. |
|---|
| 1020 | 1071 | (dev->version.major_version == HBM_MAJOR_VERSION_DR && |
|---|
| 1021 | 1072 | dev->version.minor_version >= HBM_MINOR_VERSION_DR)) |
|---|
| 1022 | 1073 | dev->hbm_f_dr_supported = 1; |
|---|
| 1074 | + |
|---|
| 1075 | + /* VTag Support */ |
|---|
| 1076 | + dev->hbm_f_vt_supported = 0; |
|---|
| 1077 | + if (dev->version.major_version > HBM_MAJOR_VERSION_VT || |
|---|
| 1078 | + (dev->version.major_version == HBM_MAJOR_VERSION_VT && |
|---|
| 1079 | + dev->version.minor_version >= HBM_MINOR_VERSION_VT)) |
|---|
| 1080 | + dev->hbm_f_vt_supported = 1; |
|---|
| 1081 | + |
|---|
| 1082 | + /* Capability message Support */ |
|---|
| 1083 | + dev->hbm_f_cap_supported = 0; |
|---|
| 1084 | + if (dev->version.major_version > HBM_MAJOR_VERSION_CAP || |
|---|
| 1085 | + (dev->version.major_version == HBM_MAJOR_VERSION_CAP && |
|---|
| 1086 | + dev->version.minor_version >= HBM_MINOR_VERSION_CAP)) |
|---|
| 1087 | + dev->hbm_f_cap_supported = 1; |
|---|
| 1023 | 1088 | } |
|---|
| 1024 | 1089 | |
|---|
| 1025 | 1090 | /** |
|---|
| .. | .. |
|---|
| 1051 | 1116 | struct hbm_host_version_response *version_res; |
|---|
| 1052 | 1117 | struct hbm_props_response *props_res; |
|---|
| 1053 | 1118 | struct hbm_host_enum_response *enum_res; |
|---|
| 1119 | + struct hbm_dma_setup_response *dma_setup_res; |
|---|
| 1054 | 1120 | struct hbm_add_client_request *add_cl_req; |
|---|
| 1121 | + struct hbm_capability_response *capability_res; |
|---|
| 1055 | 1122 | int ret; |
|---|
| 1056 | 1123 | |
|---|
| 1057 | 1124 | struct mei_hbm_cl_cmd *cl_cmd; |
|---|
| .. | .. |
|---|
| 1115 | 1182 | return -EPROTO; |
|---|
| 1116 | 1183 | } |
|---|
| 1117 | 1184 | |
|---|
| 1118 | | - if (mei_hbm_enum_clients_req(dev)) { |
|---|
| 1119 | | - dev_err(dev->dev, "hbm: start: failed to send enumeration request\n"); |
|---|
| 1120 | | - return -EIO; |
|---|
| 1185 | + if (dev->hbm_f_cap_supported) { |
|---|
| 1186 | + if (mei_hbm_capabilities_req(dev)) |
|---|
| 1187 | + return -EIO; |
|---|
| 1188 | + wake_up(&dev->wait_hbm_start); |
|---|
| 1189 | + break; |
|---|
| 1121 | 1190 | } |
|---|
| 1122 | 1191 | |
|---|
| 1192 | + if (dev->hbm_f_dr_supported) { |
|---|
| 1193 | + if (mei_dmam_ring_alloc(dev)) |
|---|
| 1194 | + dev_info(dev->dev, "running w/o dma ring\n"); |
|---|
| 1195 | + if (mei_dma_ring_is_allocated(dev)) { |
|---|
| 1196 | + if (mei_hbm_dma_setup_req(dev)) |
|---|
| 1197 | + return -EIO; |
|---|
| 1198 | + |
|---|
| 1199 | + wake_up(&dev->wait_hbm_start); |
|---|
| 1200 | + break; |
|---|
| 1201 | + } |
|---|
| 1202 | + } |
|---|
| 1203 | + |
|---|
| 1204 | + dev->hbm_f_dr_supported = 0; |
|---|
| 1205 | + mei_dmam_ring_free(dev); |
|---|
| 1206 | + |
|---|
| 1207 | + if (mei_hbm_enum_clients_req(dev)) |
|---|
| 1208 | + return -EIO; |
|---|
| 1209 | + |
|---|
| 1123 | 1210 | wake_up(&dev->wait_hbm_start); |
|---|
| 1211 | + break; |
|---|
| 1212 | + |
|---|
| 1213 | + case MEI_HBM_CAPABILITIES_RES_CMD: |
|---|
| 1214 | + dev_dbg(dev->dev, "hbm: capabilities response: message received.\n"); |
|---|
| 1215 | + |
|---|
| 1216 | + dev->init_clients_timer = 0; |
|---|
| 1217 | + |
|---|
| 1218 | + if (dev->hbm_state != MEI_HBM_CAP_SETUP) { |
|---|
| 1219 | + dev_err(dev->dev, "hbm: capabilities response: state mismatch, [%d, %d]\n", |
|---|
| 1220 | + dev->dev_state, dev->hbm_state); |
|---|
| 1221 | + return -EPROTO; |
|---|
| 1222 | + } |
|---|
| 1223 | + |
|---|
| 1224 | + capability_res = (struct hbm_capability_response *)mei_msg; |
|---|
| 1225 | + if (!(capability_res->capability_granted[0] & HBM_CAP_VT)) |
|---|
| 1226 | + dev->hbm_f_vt_supported = 0; |
|---|
| 1227 | + |
|---|
| 1228 | + if (dev->hbm_f_dr_supported) { |
|---|
| 1229 | + if (mei_dmam_ring_alloc(dev)) |
|---|
| 1230 | + dev_info(dev->dev, "running w/o dma ring\n"); |
|---|
| 1231 | + if (mei_dma_ring_is_allocated(dev)) { |
|---|
| 1232 | + if (mei_hbm_dma_setup_req(dev)) |
|---|
| 1233 | + return -EIO; |
|---|
| 1234 | + break; |
|---|
| 1235 | + } |
|---|
| 1236 | + } |
|---|
| 1237 | + |
|---|
| 1238 | + dev->hbm_f_dr_supported = 0; |
|---|
| 1239 | + mei_dmam_ring_free(dev); |
|---|
| 1240 | + |
|---|
| 1241 | + if (mei_hbm_enum_clients_req(dev)) |
|---|
| 1242 | + return -EIO; |
|---|
| 1243 | + break; |
|---|
| 1244 | + |
|---|
| 1245 | + case MEI_HBM_DMA_SETUP_RES_CMD: |
|---|
| 1246 | + dev_dbg(dev->dev, "hbm: dma setup response: message received.\n"); |
|---|
| 1247 | + |
|---|
| 1248 | + dev->init_clients_timer = 0; |
|---|
| 1249 | + |
|---|
| 1250 | + if (dev->hbm_state != MEI_HBM_DR_SETUP) { |
|---|
| 1251 | + dev_err(dev->dev, "hbm: dma setup response: state mismatch, [%d, %d]\n", |
|---|
| 1252 | + dev->dev_state, dev->hbm_state); |
|---|
| 1253 | + return -EPROTO; |
|---|
| 1254 | + } |
|---|
| 1255 | + |
|---|
| 1256 | + dma_setup_res = (struct hbm_dma_setup_response *)mei_msg; |
|---|
| 1257 | + |
|---|
| 1258 | + if (dma_setup_res->status) { |
|---|
| 1259 | + u8 status = dma_setup_res->status; |
|---|
| 1260 | + |
|---|
| 1261 | + if (status == MEI_HBMS_NOT_ALLOWED) { |
|---|
| 1262 | + dev_dbg(dev->dev, "hbm: dma setup not allowed\n"); |
|---|
| 1263 | + } else { |
|---|
| 1264 | + dev_info(dev->dev, "hbm: dma setup response: failure = %d %s\n", |
|---|
| 1265 | + status, |
|---|
| 1266 | + mei_hbm_status_str(status)); |
|---|
| 1267 | + } |
|---|
| 1268 | + dev->hbm_f_dr_supported = 0; |
|---|
| 1269 | + mei_dmam_ring_free(dev); |
|---|
| 1270 | + } |
|---|
| 1271 | + |
|---|
| 1272 | + if (mei_hbm_enum_clients_req(dev)) |
|---|
| 1273 | + return -EIO; |
|---|
| 1124 | 1274 | break; |
|---|
| 1125 | 1275 | |
|---|
| 1126 | 1276 | case CLIENT_CONNECT_RES_CMD: |
|---|
| .. | .. |
|---|
| 1223 | 1373 | return -EPROTO; |
|---|
| 1224 | 1374 | } |
|---|
| 1225 | 1375 | |
|---|
| 1226 | | - dev->dev_state = MEI_DEV_POWER_DOWN; |
|---|
| 1376 | + mei_set_devstate(dev, MEI_DEV_POWER_DOWN); |
|---|
| 1227 | 1377 | dev_info(dev->dev, "hbm: stop response: resetting.\n"); |
|---|
| 1228 | 1378 | /* force the reset */ |
|---|
| 1229 | 1379 | return -EPROTO; |
|---|
| .. | .. |
|---|
| 1278 | 1428 | break; |
|---|
| 1279 | 1429 | |
|---|
| 1280 | 1430 | default: |
|---|
| 1281 | | - BUG(); |
|---|
| 1282 | | - break; |
|---|
| 1431 | + WARN(1, "hbm: wrong command %d\n", mei_msg->hbm_cmd); |
|---|
| 1432 | + return -EPROTO; |
|---|
| 1283 | 1433 | |
|---|
| 1284 | 1434 | } |
|---|
| 1285 | 1435 | return 0; |
|---|