cmd.c revision 691cdb49388b808bfbfacaea93afb5c2807db45e
1/* 2 * Copyright (C) 2008, cozybit Inc. 3 * Copyright (C) 2003-2006, Marvell International Ltd. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or (at 8 * your option) any later version. 9 */ 10#include "libertas_tf.h" 11 12static const struct channel_range channel_ranges[] = { 13 { LBTF_REGDOMAIN_US, 1, 12 }, 14 { LBTF_REGDOMAIN_CA, 1, 12 }, 15 { LBTF_REGDOMAIN_EU, 1, 14 }, 16 { LBTF_REGDOMAIN_JP, 1, 14 }, 17 { LBTF_REGDOMAIN_SP, 1, 14 }, 18 { LBTF_REGDOMAIN_FR, 1, 14 }, 19}; 20 21static u16 lbtf_region_code_to_index[MRVDRV_MAX_REGION_CODE] = 22{ 23 LBTF_REGDOMAIN_US, LBTF_REGDOMAIN_CA, LBTF_REGDOMAIN_EU, 24 LBTF_REGDOMAIN_SP, LBTF_REGDOMAIN_FR, LBTF_REGDOMAIN_JP, 25}; 26 27static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv); 28 29 30/** 31 * lbtf_cmd_copyback - Simple callback that copies response back into command 32 * 33 * @priv A pointer to struct lbtf_private structure 34 * @extra A pointer to the original command structure for which 35 * 'resp' is a response 36 * @resp A pointer to the command response 37 * 38 * Returns: 0 on success, error on failure 39 */ 40int lbtf_cmd_copyback(struct lbtf_private *priv, unsigned long extra, 41 struct cmd_header *resp) 42{ 43 struct cmd_header *buf = (void *)extra; 44 uint16_t copy_len; 45 46 copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); 47 memcpy(buf, resp, copy_len); 48 return 0; 49} 50EXPORT_SYMBOL_GPL(lbtf_cmd_copyback); 51 52#define CHAN_TO_IDX(chan) ((chan) - 1) 53 54static void lbtf_geo_init(struct lbtf_private *priv) 55{ 56 const struct channel_range *range = channel_ranges; 57 u8 ch; 58 int i; 59 60 for (i = 0; i < ARRAY_SIZE(channel_ranges); i++) 61 if (channel_ranges[i].regdomain == priv->regioncode) { 62 range = &channel_ranges[i]; 63 break; 64 } 65 66 for (ch = priv->range.start; ch < priv->range.end; ch++) 67 priv->channels[CHAN_TO_IDX(ch)].flags = 0; 68} 69 70/** 71 * lbtf_update_hw_spec: Updates the hardware details. 72 * 73 * @priv A pointer to struct lbtf_private structure 74 * 75 * Returns: 0 on success, error on failure 76 */ 77int lbtf_update_hw_spec(struct lbtf_private *priv) 78{ 79 struct cmd_ds_get_hw_spec cmd; 80 int ret = -1; 81 u32 i; 82 DECLARE_MAC_BUF(mac); 83 84 memset(&cmd, 0, sizeof(cmd)); 85 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 86 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN); 87 ret = lbtf_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd); 88 if (ret) 89 goto out; 90 91 priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo); 92 93 /* The firmware release is in an interesting format: the patch 94 * level is in the most significant nibble ... so fix that: */ 95 priv->fwrelease = le32_to_cpu(cmd.fwrelease); 96 priv->fwrelease = (priv->fwrelease << 8) | 97 (priv->fwrelease >> 24 & 0xff); 98 99 printk(KERN_INFO "libertastf: %s, fw %u.%u.%up%u, cap 0x%08x\n", 100 print_mac(mac, cmd.permanentaddr), 101 priv->fwrelease >> 24 & 0xff, 102 priv->fwrelease >> 16 & 0xff, 103 priv->fwrelease >> 8 & 0xff, 104 priv->fwrelease & 0xff, 105 priv->fwcapinfo); 106 107 /* Clamp region code to 8-bit since FW spec indicates that it should 108 * only ever be 8-bit, even though the field size is 16-bit. Some 109 * firmware returns non-zero high 8 bits here. 110 */ 111 priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; 112 113 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { 114 /* use the region code to search for the index */ 115 if (priv->regioncode == lbtf_region_code_to_index[i]) 116 break; 117 } 118 119 /* if it's unidentified region code, use the default (USA) */ 120 if (i >= MRVDRV_MAX_REGION_CODE) 121 priv->regioncode = 0x10; 122 123 if (priv->current_addr[0] == 0xff) 124 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); 125 126 SET_IEEE80211_PERM_ADDR(priv->hw, priv->current_addr); 127 128 lbtf_geo_init(priv); 129out: 130 return ret; 131} 132 133/** 134 * lbtf_set_channel: Set the radio channel 135 * 136 * @priv A pointer to struct lbtf_private structure 137 * @channel The desired channel, or 0 to clear a locked channel 138 * 139 * Returns: 0 on success, error on failure 140 */ 141int lbtf_set_channel(struct lbtf_private *priv, u8 channel) 142{ 143 struct cmd_ds_802_11_rf_channel cmd; 144 145 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 146 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); 147 cmd.channel = cpu_to_le16(channel); 148 149 return lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); 150} 151 152int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon) 153{ 154 struct cmd_ds_802_11_beacon_set cmd; 155 int size; 156 157 if (beacon->len > MRVL_MAX_BCN_SIZE) 158 return -1; 159 size = sizeof(cmd) - sizeof(cmd.beacon) + beacon->len; 160 cmd.hdr.size = cpu_to_le16(size); 161 cmd.len = cpu_to_le16(beacon->len); 162 memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len); 163 164 lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size); 165 return 0; 166} 167 168int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable, 169 int beacon_int) { 170 struct cmd_ds_802_11_beacon_control cmd; 171 172 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 173 cmd.action = cpu_to_le16(CMD_ACT_SET); 174 cmd.beacon_enable = cpu_to_le16(beacon_enable); 175 cmd.beacon_period = cpu_to_le16(beacon_int); 176 177 lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd)); 178 return 0; 179} 180 181static void lbtf_queue_cmd(struct lbtf_private *priv, 182 struct cmd_ctrl_node *cmdnode) 183{ 184 unsigned long flags; 185 186 if (!cmdnode) 187 return; 188 189 if (!cmdnode->cmdbuf->size) 190 return; 191 192 cmdnode->result = 0; 193 spin_lock_irqsave(&priv->driver_lock, flags); 194 list_add_tail(&cmdnode->list, &priv->cmdpendingq); 195 spin_unlock_irqrestore(&priv->driver_lock, flags); 196} 197 198static void lbtf_submit_command(struct lbtf_private *priv, 199 struct cmd_ctrl_node *cmdnode) 200{ 201 unsigned long flags; 202 struct cmd_header *cmd; 203 uint16_t cmdsize; 204 uint16_t command; 205 int timeo = 5 * HZ; 206 int ret; 207 208 cmd = cmdnode->cmdbuf; 209 210 spin_lock_irqsave(&priv->driver_lock, flags); 211 priv->cur_cmd = cmdnode; 212 cmdsize = le16_to_cpu(cmd->size); 213 command = le16_to_cpu(cmd->command); 214 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); 215 spin_unlock_irqrestore(&priv->driver_lock, flags); 216 217 if (ret) 218 /* Let the timer kick in and retry, and potentially reset 219 the whole thing if the condition persists */ 220 timeo = HZ; 221 222 /* Setup the timer after transmit command */ 223 mod_timer(&priv->command_timer, jiffies + timeo); 224} 225 226/** 227 * This function inserts command node to cmdfreeq 228 * after cleans it. Requires priv->driver_lock held. 229 */ 230static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, 231 struct cmd_ctrl_node *cmdnode) 232{ 233 if (!cmdnode) 234 return; 235 236 cmdnode->callback = NULL; 237 cmdnode->callback_arg = 0; 238 239 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); 240 241 list_add_tail(&cmdnode->list, &priv->cmdfreeq); 242} 243 244static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv, 245 struct cmd_ctrl_node *ptempcmd) 246{ 247 unsigned long flags; 248 249 spin_lock_irqsave(&priv->driver_lock, flags); 250 __lbtf_cleanup_and_insert_cmd(priv, ptempcmd); 251 spin_unlock_irqrestore(&priv->driver_lock, flags); 252} 253 254void lbtf_complete_command(struct lbtf_private *priv, struct cmd_ctrl_node *cmd, 255 int result) 256{ 257 cmd->result = result; 258 cmd->cmdwaitqwoken = 1; 259 wake_up_interruptible(&cmd->cmdwait_q); 260 261 if (!cmd->callback) 262 __lbtf_cleanup_and_insert_cmd(priv, cmd); 263 priv->cur_cmd = NULL; 264} 265 266int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv) 267{ 268 struct cmd_ds_mac_multicast_addr cmd; 269 270 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 271 cmd.action = cpu_to_le16(CMD_ACT_SET); 272 273 cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr); 274 memcpy(cmd.maclist, priv->multicastlist, 275 priv->nr_of_multicastmacaddr * ETH_ALEN); 276 277 lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd)); 278 return 0; 279} 280 281void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode) 282{ 283 struct cmd_ds_set_mode cmd; 284 285 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 286 cmd.mode = cpu_to_le16(mode); 287 lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd)); 288} 289 290void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid) 291{ 292 struct cmd_ds_set_bssid cmd; 293 294 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 295 cmd.activate = activate ? 1 : 0; 296 if (activate) 297 memcpy(cmd.bssid, bssid, ETH_ALEN); 298 299 lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd)); 300} 301 302int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr) 303{ 304 struct cmd_ds_802_11_mac_address cmd; 305 306 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 307 cmd.action = cpu_to_le16(CMD_ACT_SET); 308 309 memcpy(cmd.macadd, mac_addr, ETH_ALEN); 310 311 lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd)); 312 return 0; 313} 314 315int lbtf_set_radio_control(struct lbtf_private *priv) 316{ 317 int ret = 0; 318 struct cmd_ds_802_11_radio_control cmd; 319 320 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 321 cmd.action = cpu_to_le16(CMD_ACT_SET); 322 323 switch (priv->preamble) { 324 case CMD_TYPE_SHORT_PREAMBLE: 325 cmd.control = cpu_to_le16(SET_SHORT_PREAMBLE); 326 break; 327 328 case CMD_TYPE_LONG_PREAMBLE: 329 cmd.control = cpu_to_le16(SET_LONG_PREAMBLE); 330 break; 331 332 case CMD_TYPE_AUTO_PREAMBLE: 333 default: 334 cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE); 335 break; 336 } 337 338 if (priv->radioon) 339 cmd.control |= cpu_to_le16(TURN_ON_RF); 340 else 341 cmd.control &= cpu_to_le16(~TURN_ON_RF); 342 343 ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); 344 return ret; 345} 346 347void lbtf_set_mac_control(struct lbtf_private *priv) 348{ 349 struct cmd_ds_mac_control cmd; 350 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 351 cmd.action = cpu_to_le16(priv->mac_control); 352 cmd.reserved = 0; 353 354 lbtf_cmd_async(priv, CMD_MAC_CONTROL, 355 &cmd.hdr, sizeof(cmd)); 356} 357 358/** 359 * lbtf_allocate_cmd_buffer - Allocates cmd buffer, links it to free cmd queue 360 * 361 * @priv A pointer to struct lbtf_private structure 362 * 363 * Returns: 0 on success. 364 */ 365int lbtf_allocate_cmd_buffer(struct lbtf_private *priv) 366{ 367 u32 bufsize; 368 u32 i; 369 struct cmd_ctrl_node *cmdarray; 370 371 /* Allocate and initialize the command array */ 372 bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; 373 cmdarray = kzalloc(bufsize, GFP_KERNEL); 374 if (!cmdarray) 375 return -1; 376 priv->cmd_array = cmdarray; 377 378 /* Allocate and initialize each command buffer in the command array */ 379 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 380 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); 381 if (!cmdarray[i].cmdbuf) 382 return -1; 383 } 384 385 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 386 init_waitqueue_head(&cmdarray[i].cmdwait_q); 387 lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]); 388 } 389 return 0; 390} 391 392/** 393 * lbtf_free_cmd_buffer - Frees the cmd buffer. 394 * 395 * @priv A pointer to struct lbtf_private structure 396 * 397 * Returns: 0 398 */ 399int lbtf_free_cmd_buffer(struct lbtf_private *priv) 400{ 401 struct cmd_ctrl_node *cmdarray; 402 unsigned int i; 403 404 /* need to check if cmd array is allocated or not */ 405 if (priv->cmd_array == NULL) 406 return 0; 407 408 cmdarray = priv->cmd_array; 409 410 /* Release shared memory buffers */ 411 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 412 kfree(cmdarray[i].cmdbuf); 413 cmdarray[i].cmdbuf = NULL; 414 } 415 416 /* Release cmd_ctrl_node */ 417 kfree(priv->cmd_array); 418 priv->cmd_array = NULL; 419 420 return 0; 421} 422 423/** 424 * lbtf_get_cmd_ctrl_node - Gets free cmd node from free cmd queue. 425 * 426 * @priv A pointer to struct lbtf_private structure 427 * 428 * Returns: pointer to a struct cmd_ctrl_node or NULL if none available. 429 */ 430static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv) 431{ 432 struct cmd_ctrl_node *tempnode; 433 unsigned long flags; 434 435 if (!priv) 436 return NULL; 437 438 spin_lock_irqsave(&priv->driver_lock, flags); 439 440 if (!list_empty(&priv->cmdfreeq)) { 441 tempnode = list_first_entry(&priv->cmdfreeq, 442 struct cmd_ctrl_node, list); 443 list_del(&tempnode->list); 444 } else 445 tempnode = NULL; 446 447 spin_unlock_irqrestore(&priv->driver_lock, flags); 448 449 return tempnode; 450} 451 452/** 453 * lbtf_execute_next_command: execute next command in cmd pending queue. 454 * 455 * @priv A pointer to struct lbtf_private structure 456 * 457 * Returns: 0 on success. 458 */ 459int lbtf_execute_next_command(struct lbtf_private *priv) 460{ 461 struct cmd_ctrl_node *cmdnode = NULL; 462 struct cmd_header *cmd; 463 unsigned long flags; 464 465 /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the 466 * only caller to us is lbtf_thread() and we get even when a 467 * data packet is received */ 468 469 spin_lock_irqsave(&priv->driver_lock, flags); 470 471 if (priv->cur_cmd) { 472 spin_unlock_irqrestore(&priv->driver_lock, flags); 473 return -1; 474 } 475 476 if (!list_empty(&priv->cmdpendingq)) { 477 cmdnode = list_first_entry(&priv->cmdpendingq, 478 struct cmd_ctrl_node, list); 479 } 480 481 if (cmdnode) { 482 cmd = cmdnode->cmdbuf; 483 484 list_del(&cmdnode->list); 485 spin_unlock_irqrestore(&priv->driver_lock, flags); 486 lbtf_submit_command(priv, cmdnode); 487 } else 488 spin_unlock_irqrestore(&priv->driver_lock, flags); 489 return 0; 490} 491 492static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv, 493 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, 494 int (*callback)(struct lbtf_private *, unsigned long, 495 struct cmd_header *), 496 unsigned long callback_arg) 497{ 498 struct cmd_ctrl_node *cmdnode; 499 500 if (priv->surpriseremoved) 501 return ERR_PTR(-ENOENT); 502 503 cmdnode = lbtf_get_cmd_ctrl_node(priv); 504 if (cmdnode == NULL) { 505 /* Wake up main thread to execute next command */ 506 queue_work(lbtf_wq, &priv->cmd_work); 507 return ERR_PTR(-ENOBUFS); 508 } 509 510 cmdnode->callback = callback; 511 cmdnode->callback_arg = callback_arg; 512 513 /* Copy the incoming command to the buffer */ 514 memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); 515 516 /* Set sequence number, clean result, move to buffer */ 517 priv->seqnum++; 518 cmdnode->cmdbuf->command = cpu_to_le16(command); 519 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); 520 cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); 521 cmdnode->cmdbuf->result = 0; 522 cmdnode->cmdwaitqwoken = 0; 523 lbtf_queue_cmd(priv, cmdnode); 524 queue_work(lbtf_wq, &priv->cmd_work); 525 526 return cmdnode; 527} 528 529void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command, 530 struct cmd_header *in_cmd, int in_cmd_size) 531{ 532 __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0); 533} 534 535int __lbtf_cmd(struct lbtf_private *priv, uint16_t command, 536 struct cmd_header *in_cmd, int in_cmd_size, 537 int (*callback)(struct lbtf_private *, 538 unsigned long, struct cmd_header *), 539 unsigned long callback_arg) 540{ 541 struct cmd_ctrl_node *cmdnode; 542 unsigned long flags; 543 int ret = 0; 544 545 cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, 546 callback, callback_arg); 547 if (IS_ERR(cmdnode)) 548 return PTR_ERR(cmdnode); 549 550 might_sleep(); 551 ret = wait_event_interruptible(cmdnode->cmdwait_q, 552 cmdnode->cmdwaitqwoken); 553 if (ret) { 554 printk(KERN_DEBUG 555 "libertastf: command 0x%04x interrupted by signal", 556 command); 557 return ret; 558 } 559 560 spin_lock_irqsave(&priv->driver_lock, flags); 561 ret = cmdnode->result; 562 if (ret) 563 printk(KERN_DEBUG "libertastf: command 0x%04x failed: %d\n", 564 command, ret); 565 566 __lbtf_cleanup_and_insert_cmd(priv, cmdnode); 567 spin_unlock_irqrestore(&priv->driver_lock, flags); 568 569 return ret; 570} 571EXPORT_SYMBOL_GPL(__lbtf_cmd); 572 573/* Call holding driver_lock */ 574void lbtf_cmd_response_rx(struct lbtf_private *priv) 575{ 576 priv->cmd_response_rxed = 1; 577 queue_work(lbtf_wq, &priv->cmd_work); 578} 579EXPORT_SYMBOL_GPL(lbtf_cmd_response_rx); 580 581int lbtf_process_rx_command(struct lbtf_private *priv) 582{ 583 uint16_t respcmd, curcmd; 584 struct cmd_header *resp; 585 int ret = 0; 586 unsigned long flags; 587 uint16_t result; 588 589 mutex_lock(&priv->lock); 590 spin_lock_irqsave(&priv->driver_lock, flags); 591 592 if (!priv->cur_cmd) { 593 ret = -1; 594 spin_unlock_irqrestore(&priv->driver_lock, flags); 595 goto done; 596 } 597 598 resp = (void *)priv->cmd_resp_buff; 599 curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command); 600 respcmd = le16_to_cpu(resp->command); 601 result = le16_to_cpu(resp->result); 602 603 if (net_ratelimit()) 604 printk(KERN_DEBUG "libertastf: cmd response 0x%04x, seq %d, size %d\n", 605 respcmd, le16_to_cpu(resp->seqnum), 606 le16_to_cpu(resp->size)); 607 608 if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) { 609 spin_unlock_irqrestore(&priv->driver_lock, flags); 610 ret = -1; 611 goto done; 612 } 613 if (respcmd != CMD_RET(curcmd)) { 614 spin_unlock_irqrestore(&priv->driver_lock, flags); 615 ret = -1; 616 goto done; 617 } 618 619 if (resp->result == cpu_to_le16(0x0004)) { 620 /* 0x0004 means -EAGAIN. Drop the response, let it time out 621 and be resubmitted */ 622 spin_unlock_irqrestore(&priv->driver_lock, flags); 623 ret = -1; 624 goto done; 625 } 626 627 /* Now we got response from FW, cancel the command timer */ 628 del_timer(&priv->command_timer); 629 priv->cmd_timed_out = 0; 630 if (priv->nr_retries) 631 priv->nr_retries = 0; 632 633 /* If the command is not successful, cleanup and return failure */ 634 if ((result != 0 || !(respcmd & 0x8000))) { 635 /* 636 * Handling errors here 637 */ 638 switch (respcmd) { 639 case CMD_RET(CMD_GET_HW_SPEC): 640 case CMD_RET(CMD_802_11_RESET): 641 printk(KERN_DEBUG "libertastf: reset failed\n"); 642 break; 643 644 } 645 lbtf_complete_command(priv, priv->cur_cmd, result); 646 spin_unlock_irqrestore(&priv->driver_lock, flags); 647 648 ret = -1; 649 goto done; 650 } 651 652 spin_unlock_irqrestore(&priv->driver_lock, flags); 653 654 if (priv->cur_cmd && priv->cur_cmd->callback) { 655 ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg, 656 resp); 657 } 658 spin_lock_irqsave(&priv->driver_lock, flags); 659 660 if (priv->cur_cmd) { 661 /* Clean up and Put current command back to cmdfreeq */ 662 lbtf_complete_command(priv, priv->cur_cmd, result); 663 } 664 spin_unlock_irqrestore(&priv->driver_lock, flags); 665 666done: 667 mutex_unlock(&priv->lock); 668 return ret; 669} 670