1 /*- 2 * Redistribution and use in source and binary forms, with or without 3 * modification, are permitted provided that the following conditions 4 * are met: 5 * 6 * Copyright 1994-2009 The FreeBSD Project. 7 * All rights reserved. 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY,OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * The views and conclusions contained in the software and documentation 28 * are those of the authors and should not be interpreted as representing 29 * official policies,either expressed or implied, of the FreeBSD Project. 30 * 31 * $FreeBSD: src/sys/dev/mfi/mfi_tbolt.c,v 1.00 2010/06/30 16:00:00 Bharat Gusain Exp $ 32 * FreeBSD projects/head_mfi/ r232949 33 */ 34 35 #include "opt_mfi.h" 36 37 #include <sys/param.h> 38 #include <sys/types.h> 39 #include <sys/kernel.h> 40 #include <sys/bus.h> 41 #include <sys/conf.h> 42 #include <sys/bio.h> 43 #include <sys/buf2.h> 44 #include <sys/ioccom.h> 45 #include <sys/eventhandler.h> 46 #include <sys/callout.h> 47 #include <sys/uio.h> 48 #include <sys/sysctl.h> 49 #include <sys/systm.h> 50 #include <sys/malloc.h> 51 52 #include <dev/raid/mfi/mfireg.h> 53 #include <dev/raid/mfi/mfi_ioctl.h> 54 #include <dev/raid/mfi/mfivar.h> 55 56 struct mfi_cmd_tbolt *mfi_tbolt_get_cmd(struct mfi_softc *sc); 57 union mfi_mpi2_request_descriptor * 58 mfi_tbolt_get_request_descriptor(struct mfi_softc *sc, uint16_t index); 59 void mfi_tbolt_complete_cmd(struct mfi_softc *sc); 60 int mfi_tbolt_build_io(struct mfi_softc *sc, struct mfi_command *mfi_cmd, 61 struct mfi_cmd_tbolt *cmd); 62 static inline void mfi_tbolt_return_cmd(struct mfi_softc *sc, 63 struct mfi_cmd_tbolt *cmd); 64 union mfi_mpi2_request_descriptor *mfi_tbolt_build_mpt_cmd(struct mfi_softc 65 *sc, struct mfi_command *cmd); 66 uint8_t 67 mfi_build_mpt_pass_thru(struct mfi_softc *sc, struct mfi_command *mfi_cmd); 68 union mfi_mpi2_request_descriptor *mfi_build_and_issue_cmd(struct mfi_softc 69 *sc, struct mfi_command *mfi_cmd); 70 int mfi_tbolt_is_ldio(struct mfi_command *mfi_cmd); 71 void mfi_tbolt_build_ldio(struct mfi_softc *sc, struct mfi_command *mfi_cmd, 72 struct mfi_cmd_tbolt *cmd); 73 static int mfi_tbolt_make_sgl(struct mfi_softc *sc, struct mfi_command 74 *mfi_cmd, pMpi25IeeeSgeChain64_t sgl_ptr, struct mfi_cmd_tbolt *cmd); 75 static int mfi_tbolt_build_cdb(struct mfi_softc *sc, struct mfi_command 76 *mfi_cmd, uint8_t *cdb); 77 void 78 map_tbolt_cmd_status(struct mfi_command *mfi_cmd, uint8_t status, 79 uint8_t ext_status); 80 static void mfi_issue_pending_cmds_again (struct mfi_softc *sc); 81 static void mfi_kill_hba (struct mfi_softc *sc); 82 static void mfi_process_fw_state_chg_isr(void *arg); 83 uint8_t mfi_tbolt_get_map_info(struct mfi_softc *sc); 84 85 #define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000008) 86 87 void 88 mfi_tbolt_enable_intr_ppc(struct mfi_softc *sc) 89 { 90 MFI_WRITE4(sc, MFI_OMSK, ~MFI_FUSION_ENABLE_INTERRUPT_MASK); 91 MFI_READ4(sc, MFI_OMSK); 92 } 93 94 void 95 mfi_tbolt_disable_intr_ppc(struct mfi_softc *sc) 96 { 97 MFI_WRITE4(sc, MFI_OMSK, 0xFFFFFFFF); 98 MFI_READ4(sc, MFI_OMSK); 99 } 100 101 int32_t 102 mfi_tbolt_read_fw_status_ppc(struct mfi_softc *sc) 103 { 104 return MFI_READ4(sc, MFI_OSP0); 105 } 106 107 int32_t 108 mfi_tbolt_check_clear_intr_ppc(struct mfi_softc *sc) 109 { 110 int32_t status, mfi_status = 0; 111 112 status = MFI_READ4(sc, MFI_OSTS); 113 114 if (status & 1) { 115 MFI_WRITE4(sc, MFI_OSTS, status); 116 MFI_READ4(sc, MFI_OSTS); 117 if (status & MFI_STATE_CHANGE_INTERRUPT) { 118 mfi_status |= MFI_FIRMWARE_STATE_CHANGE; 119 } 120 121 return mfi_status; 122 } 123 if (!(status & MFI_FUSION_ENABLE_INTERRUPT_MASK)) 124 return 1; 125 126 MFI_READ4(sc, MFI_OSTS); 127 return 0; 128 } 129 130 131 void 132 mfi_tbolt_issue_cmd_ppc(struct mfi_softc *sc, bus_addr_t bus_add, 133 uint32_t frame_cnt) 134 { 135 bus_add |= (MFI_REQ_DESCRIPT_FLAGS_MFA 136 << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 137 MFI_WRITE4(sc, MFI_IQPL, (uint32_t)bus_add); 138 MFI_WRITE4(sc, MFI_IQPH, (uint32_t)((uint64_t)bus_add >> 32)); 139 } 140 141 /** 142 * mfi_tbolt_adp_reset - For controller reset 143 * @regs: MFI register set 144 */ 145 int mfi_tbolt_adp_reset(struct mfi_softc *sc) 146 { 147 int retry = 0, i = 0; 148 int HostDiag; 149 150 MFI_WRITE4(sc, MFI_WSR, 0xF); 151 MFI_WRITE4(sc, MFI_WSR, 4); 152 MFI_WRITE4(sc, MFI_WSR, 0xB); 153 MFI_WRITE4(sc, MFI_WSR, 2); 154 MFI_WRITE4(sc, MFI_WSR, 7); 155 MFI_WRITE4(sc, MFI_WSR, 0xD); 156 157 for (i = 0; i < 10000; i++) ; 158 159 HostDiag = (uint32_t)MFI_READ4(sc, MFI_HDR); 160 161 while (!( HostDiag & DIAG_WRITE_ENABLE)) { 162 for (i = 0; i < 1000; i++); 163 HostDiag = (uint32_t)MFI_READ4(sc, MFI_HDR); 164 device_printf(sc->mfi_dev, "ADP_RESET_TBOLT: retry time=%x, " 165 "hostdiag=%x\n", retry, HostDiag); 166 167 if (retry++ >= 100) 168 return 1; 169 } 170 171 device_printf(sc->mfi_dev, "ADP_RESET_TBOLT: HostDiag=%x\n", HostDiag); 172 173 MFI_WRITE4(sc, MFI_HDR, (HostDiag | DIAG_RESET_ADAPTER)); 174 175 for (i=0; i < 10; i++) { 176 for (i = 0; i < 10000; i++); 177 } 178 179 HostDiag = (uint32_t)MFI_READ4(sc, MFI_RSR); 180 while (HostDiag & DIAG_RESET_ADAPTER) { 181 for (i = 0; i < 1000; i++) ; 182 HostDiag = (uint32_t)MFI_READ4(sc, MFI_RSR); 183 device_printf(sc->mfi_dev, "ADP_RESET_TBOLT: retry time=%x, " 184 "hostdiag=%x\n", retry, HostDiag); 185 186 if (retry++ >= 1000) 187 return 1; 188 } 189 return 0; 190 } 191 192 /* 193 ******************************************************************************************* 194 * Description: 195 * This routine initialize Thunderbolt specific device information 196 ******************************************************************************************* 197 */ 198 void mfi_tbolt_init_globals(struct mfi_softc *sc) 199 { 200 /* Initialize single reply size and Message size */ 201 sc->reply_size = MEGASAS_THUNDERBOLT_REPLY_SIZE; 202 sc->raid_io_msg_size = MEGASAS_THUNDERBOLT_NEW_MSG_SIZE; 203 204 /* 205 * Calculating how many SGEs allowed in a allocated main message 206 * (size of the Message - Raid SCSI IO message size(except SGE)) 207 * / size of SGE 208 * (0x100 - (0x90 - 0x10)) / 0x10 = 8 209 */ 210 sc->max_SGEs_in_main_message = 211 (uint8_t)((sc->raid_io_msg_size 212 - (sizeof(struct mfi_mpi2_request_raid_scsi_io) 213 - sizeof(MPI2_SGE_IO_UNION))) / sizeof(MPI2_SGE_IO_UNION)); 214 /* 215 * (Command frame size allocaed in SRB ext - Raid SCSI IO message size) 216 * / size of SGL ; 217 * (1280 - 256) / 16 = 64 218 */ 219 sc->max_SGEs_in_chain_message = (MR_COMMAND_SIZE 220 - sc->raid_io_msg_size) / sizeof(MPI2_SGE_IO_UNION); 221 /* 222 * (0x08-1) + 0x40 = 0x47 - 0x01 = 0x46 one is left for command 223 * colscing 224 */ 225 sc->mfi_max_sge = (sc->max_SGEs_in_main_message - 1) 226 + sc->max_SGEs_in_chain_message - 1; 227 /* 228 * This is the offset in number of 4 * 32bit words to the next chain 229 * (0x100 - 0x10)/0x10 = 0xF(15) 230 */ 231 sc->chain_offset_value_for_main_message = (sc->raid_io_msg_size 232 - sizeof(MPI2_SGE_IO_UNION))/16; 233 sc->chain_offset_value_for_mpt_ptmsg 234 = offsetof(struct mfi_mpi2_request_raid_scsi_io, SGL)/16; 235 sc->mfi_cmd_pool_tbolt = NULL; 236 sc->request_desc_pool = NULL; 237 } 238 239 /* 240 **************************************************************************** 241 * Description: 242 * This function calculates the memory requirement for Thunderbolt 243 * controller 244 * Return Value: 245 * Total required memory in bytes 246 **************************************************************************** 247 */ 248 249 uint32_t mfi_tbolt_get_memory_requirement(struct mfi_softc *sc) 250 { 251 uint32_t size; 252 253 size = MEGASAS_THUNDERBOLT_MSG_ALLIGNMENT; /* for Alignment */ 254 size += sc->raid_io_msg_size * (sc->mfi_max_fw_cmds + 1); 255 size += sc->reply_size * sc->mfi_max_fw_cmds; 256 /* this is for SGL's */ 257 size += MEGASAS_MAX_SZ_CHAIN_FRAME * sc->mfi_max_fw_cmds; 258 return size; 259 } 260 261 /* 262 **************************************************************************** 263 * Description: 264 * This function will prepare message pools for the Thunderbolt controller 265 * Arguments: 266 * DevExt - HBA miniport driver's adapter data storage structure 267 * pMemLocation - start of the memory allocated for Thunderbolt. 268 * Return Value: 269 * TRUE if successful 270 * FALSE if failed 271 **************************************************************************** 272 */ 273 int mfi_tbolt_init_desc_pool(struct mfi_softc *sc, uint8_t* mem_location, 274 uint32_t tbolt_contg_length) 275 { 276 uint32_t offset = 0; 277 uint8_t *addr = mem_location; 278 279 /* Request Descriptor Base physical Address */ 280 281 /* For Request Decriptors Virtual Memory */ 282 /* Initialise the aligned IO Frames Virtual Memory Pointer */ 283 if (((uintptr_t)addr) & (0xFF)) { 284 addr = &addr[sc->raid_io_msg_size]; 285 addr = (uint8_t *)((uintptr_t)addr & (~0xFF)); 286 sc->request_message_pool_align = addr; 287 } else 288 sc->request_message_pool_align = addr; 289 290 offset = sc->request_message_pool_align - sc->request_message_pool; 291 sc->request_msg_busaddr = sc->mfi_tb_busaddr + offset; 292 293 /* DJA XXX should this be bus dma ??? */ 294 /* Skip request message pool */ 295 addr = &addr[sc->raid_io_msg_size * (sc->mfi_max_fw_cmds + 1)]; 296 /* Reply Frame Pool is initialized */ 297 sc->reply_frame_pool = (struct mfi_mpi2_reply_header *) addr; 298 if (((uintptr_t)addr) & (0xFF)) { 299 addr = &addr[sc->reply_size]; 300 addr = (uint8_t *)((uintptr_t)addr & (~0xFF)); 301 } 302 sc->reply_frame_pool_align 303 = (struct mfi_mpi2_reply_header *)addr; 304 305 offset = (uintptr_t)sc->reply_frame_pool_align 306 - (uintptr_t)sc->request_message_pool; 307 sc->reply_frame_busaddr = sc->mfi_tb_busaddr + offset; 308 309 /* Skip Reply Frame Pool */ 310 addr += sc->reply_size * sc->mfi_max_fw_cmds; 311 sc->reply_pool_limit = addr; 312 313 /* initializing reply address to 0xFFFFFFFF */ 314 memset((uint8_t *)sc->reply_frame_pool, 0xFF, 315 (sc->reply_size * sc->mfi_max_fw_cmds)); 316 317 offset = sc->reply_size * sc->mfi_max_fw_cmds; 318 sc->sg_frame_busaddr = sc->reply_frame_busaddr + offset; 319 /* initialize the last_reply_idx to 0 */ 320 sc->last_reply_idx = 0; 321 offset = (sc->sg_frame_busaddr + (MEGASAS_MAX_SZ_CHAIN_FRAME * 322 sc->mfi_max_fw_cmds)) - sc->mfi_tb_busaddr; 323 if (offset > tbolt_contg_length) 324 device_printf(sc->mfi_dev, "Error:Initialized more than " 325 "allocated\n"); 326 return 0; 327 } 328 329 /* 330 **************************************************************************** 331 * Description: 332 * This routine prepare and issue INIT2 frame to the Firmware 333 **************************************************************************** 334 */ 335 336 int 337 mfi_tbolt_init_MFI_queue(struct mfi_softc *sc) 338 { 339 struct MPI2_IOC_INIT_REQUEST *mpi2IocInit; 340 struct mfi_init_frame *mfi_init; 341 uintptr_t offset = 0; 342 bus_addr_t phyAddress; 343 MFI_ADDRESS *mfiAddressTemp; 344 struct mfi_command *cm; 345 int error; 346 347 mpi2IocInit = (struct MPI2_IOC_INIT_REQUEST *)sc->mfi_tb_ioc_init_desc; 348 /* Check if initialization is already completed */ 349 if (sc->MFA_enabled) { 350 return 1; 351 } 352 353 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE); 354 if ((cm = mfi_dequeue_free(sc)) == NULL) { 355 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 356 return (EBUSY); 357 } 358 cm->cm_frame = (union mfi_frame *)((uintptr_t)sc->mfi_tb_init); 359 cm->cm_frame_busaddr = sc->mfi_tb_init_busaddr; 360 cm->cm_dmamap = sc->mfi_tb_init_dmamap; 361 cm->cm_frame->header.context = 0; 362 cm->cm_sc = sc; 363 cm->cm_index = 0; 364 365 /* 366 * Abuse the SG list area of the frame to hold the init_qinfo 367 * object; 368 */ 369 mfi_init = &cm->cm_frame->init; 370 371 bzero(mpi2IocInit, sizeof(struct MPI2_IOC_INIT_REQUEST)); 372 mpi2IocInit->Function = MPI2_FUNCTION_IOC_INIT; 373 mpi2IocInit->WhoInit = MPI2_WHOINIT_HOST_DRIVER; 374 375 /* set MsgVersion and HeaderVersion host driver was built with */ 376 mpi2IocInit->MsgVersion = MPI2_VERSION; 377 mpi2IocInit->HeaderVersion = MPI2_HEADER_VERSION; 378 mpi2IocInit->SystemRequestFrameSize = sc->raid_io_msg_size/4; 379 mpi2IocInit->ReplyDescriptorPostQueueDepth 380 = (uint16_t)sc->mfi_max_fw_cmds; 381 mpi2IocInit->ReplyFreeQueueDepth = 0; /* Not supported by MR. */ 382 383 /* Get physical address of reply frame pool */ 384 offset = (uintptr_t) sc->reply_frame_pool_align 385 - (uintptr_t)sc->request_message_pool; 386 phyAddress = sc->mfi_tb_busaddr + offset; 387 mfiAddressTemp = 388 (MFI_ADDRESS *)&mpi2IocInit->ReplyDescriptorPostQueueAddress; 389 mfiAddressTemp->u.addressLow = (uint32_t)phyAddress; 390 mfiAddressTemp->u.addressHigh = (uint32_t)((uint64_t)phyAddress >> 32); 391 392 /* Get physical address of request message pool */ 393 offset = sc->request_message_pool_align - sc->request_message_pool; 394 phyAddress = sc->mfi_tb_busaddr + offset; 395 mfiAddressTemp = (MFI_ADDRESS *)&mpi2IocInit->SystemRequestFrameBaseAddress; 396 mfiAddressTemp->u.addressLow = (uint32_t)phyAddress; 397 mfiAddressTemp->u.addressHigh = (uint32_t)((uint64_t)phyAddress >> 32); 398 mpi2IocInit->ReplyFreeQueueAddress = 0; /* Not supported by MR. */ 399 mpi2IocInit->TimeStamp = time_uptime; 400 401 if (sc->verbuf) { 402 ksnprintf((char *)sc->verbuf, strlen(MEGASAS_VERSION) + 2, "%s\n", 403 MEGASAS_VERSION); 404 mfi_init->driver_ver_lo = (uint32_t)sc->verbuf_h_busaddr; 405 mfi_init->driver_ver_hi = 406 (uint32_t)((uint64_t)sc->verbuf_h_busaddr >> 32); 407 } 408 /* Get the physical address of the mpi2 ioc init command */ 409 phyAddress = sc->mfi_tb_ioc_init_busaddr; 410 mfi_init->qinfo_new_addr_lo = (uint32_t)phyAddress; 411 mfi_init->qinfo_new_addr_hi = (uint32_t)((uint64_t)phyAddress >> 32); 412 mfi_init->header.flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 413 414 mfi_init->header.cmd = MFI_CMD_INIT; 415 mfi_init->header.data_len = sizeof(struct MPI2_IOC_INIT_REQUEST); 416 mfi_init->header.cmd_status = MFI_STAT_INVALID_STATUS; 417 418 cm->cm_data = NULL; 419 cm->cm_flags |= MFI_CMD_POLLED; 420 cm->cm_timestamp = time_uptime; 421 if ((error = mfi_mapcmd(sc, cm)) != 0) { 422 device_printf(sc->mfi_dev, "failed to send IOC init2 " 423 "command %d at %lx\n", error, (long)cm->cm_frame_busaddr); 424 mfi_release_command(cm); 425 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 426 return (error); 427 } 428 mfi_release_command(cm); 429 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 430 431 if (mfi_init->header.cmd_status == 0) { 432 sc->MFA_enabled = 1; 433 } 434 else { 435 device_printf(sc->mfi_dev, "Init command Failed %x\n", 436 mfi_init->header.cmd_status); 437 return 1; 438 } 439 440 return 0; 441 442 } 443 444 int mfi_tbolt_alloc_cmd(struct mfi_softc *sc) 445 { 446 struct mfi_cmd_tbolt *cmd; 447 bus_addr_t io_req_base_phys; 448 uint8_t *io_req_base; 449 int i = 0, j = 0, offset = 0; 450 451 /* 452 * sc->mfi_cmd_pool_tbolt is an array of struct mfi_cmd_tbolt pointers. 453 * Allocate the dynamic array first and then allocate individual 454 * commands. 455 */ 456 sc->request_desc_pool = kmalloc(sizeof( 457 union mfi_mpi2_request_descriptor) * sc->mfi_max_fw_cmds, 458 M_MFIBUF, M_NOWAIT|M_ZERO); 459 sc->mfi_cmd_pool_tbolt = kmalloc(sizeof(struct mfi_cmd_tbolt*) 460 * sc->mfi_max_fw_cmds, M_MFIBUF, M_NOWAIT|M_ZERO); 461 462 if (!sc->mfi_cmd_pool_tbolt) { 463 device_printf(sc->mfi_dev, "out of memory. Could not alloc " 464 "memory for cmd_list_fusion\n"); 465 return 1; 466 } 467 468 for (i = 0; i < sc->mfi_max_fw_cmds; i++) { 469 sc->mfi_cmd_pool_tbolt[i] = kmalloc(sizeof( 470 struct mfi_cmd_tbolt),M_MFIBUF, M_NOWAIT|M_ZERO); 471 472 if (!sc->mfi_cmd_pool_tbolt[i]) { 473 device_printf(sc->mfi_dev, "Could not alloc cmd list " 474 "fusion\n"); 475 476 for (j = 0; j < i; j++) 477 kfree(sc->mfi_cmd_pool_tbolt[j], M_MFIBUF); 478 479 kfree(sc->mfi_cmd_pool_tbolt, M_MFIBUF); 480 sc->mfi_cmd_pool_tbolt = NULL; 481 } 482 } 483 484 /* 485 * The first 256 bytes (SMID 0) is not used. Don't add to the cmd 486 *list 487 */ 488 io_req_base = sc->request_message_pool_align 489 + MEGASAS_THUNDERBOLT_NEW_MSG_SIZE; 490 io_req_base_phys = sc->request_msg_busaddr 491 + MEGASAS_THUNDERBOLT_NEW_MSG_SIZE; 492 493 /* 494 * Add all the commands to command pool (instance->cmd_pool) 495 */ 496 /* SMID 0 is reserved. Set SMID/index from 1 */ 497 498 for (i = 0; i < sc->mfi_max_fw_cmds; i++) { 499 cmd = sc->mfi_cmd_pool_tbolt[i]; 500 offset = MEGASAS_THUNDERBOLT_NEW_MSG_SIZE * i; 501 cmd->index = i + 1; 502 cmd->request_desc = (union mfi_mpi2_request_descriptor *) 503 (sc->request_desc_pool + i); 504 cmd->io_request = (struct mfi_mpi2_request_raid_scsi_io *) 505 (io_req_base + offset); 506 cmd->io_request_phys_addr = io_req_base_phys + offset; 507 cmd->sg_frame = (MPI2_SGE_IO_UNION *)(sc->reply_pool_limit 508 + i * MEGASAS_MAX_SZ_CHAIN_FRAME); 509 cmd->sg_frame_phys_addr = sc->sg_frame_busaddr + i 510 * MEGASAS_MAX_SZ_CHAIN_FRAME; 511 512 TAILQ_INSERT_TAIL(&(sc->mfi_cmd_tbolt_tqh), cmd, next); 513 } 514 return 0; 515 } 516 517 int mfi_tbolt_reset(struct mfi_softc *sc) 518 { 519 uint32_t fw_state; 520 521 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE); 522 if (atomic_read(&sc->fw_reset_no_pci_access)) { 523 device_printf(sc->mfi_dev, "NO PCI ACCESS\n"); 524 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 525 return 1; 526 } 527 528 if (sc->hw_crit_error) { 529 device_printf(sc->mfi_dev, "HW CRITICAL ERROR\n"); 530 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 531 return 1; 532 } 533 534 if (sc->mfi_flags & MFI_FLAGS_TBOLT) { 535 fw_state = sc->mfi_read_fw_status(sc); 536 if ((fw_state & MFI_FWSTATE_FAULT) == MFI_FWSTATE_FAULT) { 537 if ((sc->disableOnlineCtrlReset == 0) 538 && (sc->adpreset == 0)) { 539 device_printf(sc->mfi_dev, "Adapter RESET " 540 "condition is detected\n"); 541 sc->adpreset = 1; 542 sc->issuepend_done = 0; 543 sc->MFA_enabled = 0; 544 sc->last_reply_idx = 0; 545 mfi_process_fw_state_chg_isr(sc); 546 } 547 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 548 return 0; 549 } 550 } 551 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 552 return 1; 553 } 554 555 /* 556 * mfi_intr_tbolt - isr entry point 557 */ 558 void mfi_intr_tbolt(void *arg) 559 { 560 struct mfi_softc *sc = (struct mfi_softc *)arg; 561 562 if (sc->mfi_check_clear_intr(sc) == 1) { 563 return; 564 } 565 if (sc->mfi_detaching) 566 return; 567 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE); 568 mfi_tbolt_complete_cmd(sc); 569 if (sc->mfi_flags & MFI_FLAGS_QFRZN) 570 sc->mfi_flags &= ~MFI_FLAGS_QFRZN; 571 mfi_startio(sc); 572 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 573 return; 574 } 575 576 /** 577 * map_cmd_status - Maps FW cmd status to OS cmd status 578 * @cmd : Pointer to cmd 579 * @status : status of cmd returned by FW 580 * @ext_status : ext status of cmd returned by FW 581 */ 582 583 void 584 map_tbolt_cmd_status(struct mfi_command *mfi_cmd, uint8_t status, 585 uint8_t ext_status) 586 { 587 588 switch (status) { 589 590 case MFI_STAT_OK: 591 mfi_cmd->cm_frame->header.cmd_status = 0; 592 mfi_cmd->cm_frame->dcmd.header.cmd_status = 0; 593 break; 594 595 case MFI_STAT_SCSI_IO_FAILED: 596 case MFI_STAT_LD_INIT_IN_PROGRESS: 597 mfi_cmd->cm_frame->header.cmd_status = status; 598 mfi_cmd->cm_frame->header.scsi_status = ext_status; 599 mfi_cmd->cm_frame->dcmd.header.cmd_status = status; 600 mfi_cmd->cm_frame->dcmd.header.scsi_status 601 = ext_status; 602 break; 603 604 case MFI_STAT_SCSI_DONE_WITH_ERROR: 605 mfi_cmd->cm_frame->header.cmd_status = ext_status; 606 mfi_cmd->cm_frame->dcmd.header.cmd_status = ext_status; 607 break; 608 609 case MFI_STAT_LD_OFFLINE: 610 case MFI_STAT_DEVICE_NOT_FOUND: 611 mfi_cmd->cm_frame->header.cmd_status = status; 612 mfi_cmd->cm_frame->dcmd.header.cmd_status = status; 613 break; 614 615 default: 616 mfi_cmd->cm_frame->header.cmd_status = status; 617 mfi_cmd->cm_frame->dcmd.header.cmd_status = status; 618 break; 619 } 620 } 621 622 /** 623 * mfi_tbolt_return_cmd - Return a cmd to free command pool 624 * @instance: Adapter soft state 625 * @cmd: Command packet to be returned to free command pool 626 */ 627 static inline void 628 mfi_tbolt_return_cmd(struct mfi_softc *sc, struct mfi_cmd_tbolt *cmd) 629 { 630 mfi_lockassert(&sc->mfi_io_lock); 631 632 TAILQ_INSERT_TAIL(&sc->mfi_cmd_tbolt_tqh, cmd, next); 633 } 634 635 void mfi_tbolt_complete_cmd(struct mfi_softc *sc) 636 { 637 struct mfi_mpi2_reply_header *desc, *reply_desc; 638 struct mfi_command *cmd_mfi; /* For MFA Cmds */ 639 struct mfi_cmd_tbolt *cmd_tbolt; 640 uint16_t smid; 641 uint8_t reply_descript_type; 642 struct mfi_mpi2_request_raid_scsi_io *scsi_io_req; 643 uint32_t status, extStatus; 644 uint16_t num_completed; 645 union desc_value val; 646 647 desc = (struct mfi_mpi2_reply_header *) 648 ((uintptr_t)sc->reply_frame_pool_align 649 + sc->last_reply_idx * sc->reply_size); 650 reply_desc = desc; 651 652 if (!reply_desc) 653 device_printf(sc->mfi_dev, "reply desc is NULL!!\n"); 654 655 reply_descript_type = reply_desc->ReplyFlags 656 & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 657 if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) 658 return; 659 660 num_completed = 0; 661 val.word = ((union mfi_mpi2_reply_descriptor *)desc)->words; 662 663 /* Read Reply descriptor */ 664 while ((val.u.low != 0xFFFFFFFF) && (val.u.high != 0xFFFFFFFF)) { 665 666 smid = reply_desc->SMID; 667 if (!smid || smid > sc->mfi_max_fw_cmds + 1) { 668 device_printf(sc->mfi_dev, "smid is %x. Cannot " 669 "proceed. Returning \n", smid); 670 return; 671 } 672 673 cmd_tbolt = sc->mfi_cmd_pool_tbolt[smid - 1]; 674 cmd_mfi = &sc->mfi_commands[cmd_tbolt->sync_cmd_idx]; 675 scsi_io_req = cmd_tbolt->io_request; 676 677 /* Check if internal commands */ 678 status = cmd_mfi->cm_frame->dcmd.header.cmd_status; 679 extStatus = cmd_mfi->cm_frame->dcmd.header.scsi_status; 680 681 switch (scsi_io_req->Function) { 682 case MPI2_FUNCTION_LD_IO_REQUEST: 683 /* Regular Path IO. */ 684 /* Map the Fw Error Status. */ 685 map_tbolt_cmd_status(cmd_mfi, status, 686 extStatus); 687 if ((cmd_mfi->cm_frame->dcmd.opcode 688 == MFI_DCMD_LD_MAP_GET_INFO) 689 && (cmd_mfi->cm_frame->dcmd.mbox[1] == 1)) { 690 if (cmd_mfi->cm_frame->header.cmd_status 691 != 0) 692 device_printf(sc->mfi_dev, 693 "map sync failed\n"); 694 else { 695 sc->map_id++; 696 device_printf(sc->mfi_dev, 697 "map sync completed\n"); 698 mfi_release_command(cmd_mfi); 699 } 700 } 701 if ((cmd_mfi->cm_flags & MFI_ON_MFIQ_BUSY) 702 == MFI_ON_MFIQ_BUSY 703 && (cmd_mfi->cm_flags & MFI_CMD_POLLED) == 0) { 704 /* BHARAT poll workaround */ 705 mfi_remove_busy(cmd_mfi); 706 cmd_mfi->cm_error = 0; 707 mfi_complete(sc, cmd_mfi); 708 } 709 mfi_tbolt_return_cmd(sc, cmd_tbolt); 710 break; 711 case MPI2_FUNCTION_PASSTHRU_IO_REQUEST: 712 map_tbolt_cmd_status(cmd_mfi, status, extStatus); 713 if ((cmd_mfi->cm_frame->dcmd.opcode 714 == MFI_DCMD_LD_MAP_GET_INFO) 715 && (cmd_mfi->cm_frame->dcmd.mbox[1] == 1)) { 716 if (cmd_mfi->cm_frame->header.cmd_status != 0) 717 device_printf(sc->mfi_dev, 718 "map sync failed\n"); 719 else { 720 sc->map_id++; 721 device_printf(sc->mfi_dev, 722 "map sync completed\n"); 723 mfi_release_command(cmd_mfi); 724 } 725 } 726 if ((cmd_mfi->cm_flags & MFI_ON_MFIQ_BUSY) 727 == MFI_ON_MFIQ_BUSY 728 && (cmd_mfi->cm_flags & MFI_CMD_POLLED) == 0) { 729 /* BHARAT poll workaround */ 730 mfi_remove_busy(cmd_mfi); 731 cmd_mfi->cm_error = 0; 732 mfi_complete(sc, cmd_mfi); 733 } 734 mfi_tbolt_return_cmd(sc, cmd_tbolt); 735 break; 736 } 737 738 sc->last_reply_idx++; 739 if (sc->last_reply_idx >= sc->mfi_max_fw_cmds) { 740 MFI_WRITE4(sc, MFI_RPI, sc->last_reply_idx); 741 sc->last_reply_idx = 0; 742 } 743 /*set it back to all 0xfff.*/ 744 ((union mfi_mpi2_reply_descriptor*)desc)->words = 745 ~((uint64_t)0x00); 746 747 num_completed++; 748 749 /* Get the next reply descriptor */ 750 desc = (struct mfi_mpi2_reply_header *) 751 ((uintptr_t)sc->reply_frame_pool_align 752 + sc->last_reply_idx * sc->reply_size); 753 reply_desc = desc; 754 val.word = ((union mfi_mpi2_reply_descriptor*)desc)->words; 755 reply_descript_type = reply_desc->ReplyFlags 756 & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 757 if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) 758 break; 759 } 760 761 if (!num_completed) 762 return; 763 764 /* update replyIndex to FW */ 765 if (sc->last_reply_idx) 766 MFI_WRITE4(sc, MFI_RPI, sc->last_reply_idx); 767 768 return; 769 } 770 771 /** 772 * mfi_get_cmd - Get a command from the free pool 773 * @instance: Adapter soft state 774 * 775 * Returns a free command from the pool 776 */ 777 778 struct mfi_cmd_tbolt *mfi_tbolt_get_cmd(struct mfi_softc 779 *sc) 780 { 781 struct mfi_cmd_tbolt *cmd = NULL; 782 783 mfi_lockassert(&sc->mfi_io_lock); 784 785 cmd = TAILQ_FIRST(&sc->mfi_cmd_tbolt_tqh); 786 TAILQ_REMOVE(&sc->mfi_cmd_tbolt_tqh, cmd, next); 787 memset((uint8_t *)cmd->sg_frame, 0, MEGASAS_MAX_SZ_CHAIN_FRAME); 788 memset((uint8_t *)cmd->io_request, 0, 789 MEGASAS_THUNDERBOLT_NEW_MSG_SIZE); 790 return cmd; 791 } 792 793 union mfi_mpi2_request_descriptor * 794 mfi_tbolt_get_request_descriptor(struct mfi_softc *sc, uint16_t index) 795 { 796 uint8_t *p; 797 798 if (index >= sc->mfi_max_fw_cmds) { 799 device_printf(sc->mfi_dev, "Invalid SMID (0x%x)request " 800 "for descriptor\n", index); 801 return NULL; 802 } 803 p = sc->request_desc_pool + sizeof(union mfi_mpi2_request_descriptor) 804 * index; 805 memset(p, 0, sizeof(union mfi_mpi2_request_descriptor)); 806 return (union mfi_mpi2_request_descriptor *)p; 807 } 808 809 810 /* Used to build IOCTL cmd */ 811 uint8_t 812 mfi_build_mpt_pass_thru(struct mfi_softc *sc, struct mfi_command *mfi_cmd) 813 { 814 MPI25_IEEE_SGE_CHAIN64 *mpi25_ieee_chain; 815 struct mfi_mpi2_request_raid_scsi_io *io_req; 816 struct mfi_cmd_tbolt *cmd; 817 818 cmd = mfi_tbolt_get_cmd(sc); 819 if (!cmd) 820 return EBUSY; 821 mfi_cmd->cm_extra_frames = cmd->index; /* Frame count used as SMID */ 822 cmd->sync_cmd_idx = mfi_cmd->cm_index; 823 io_req = cmd->io_request; 824 mpi25_ieee_chain = (MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL.IeeeChain; 825 826 io_req->Function = MPI2_FUNCTION_PASSTHRU_IO_REQUEST; 827 io_req->SGLOffset0 = offsetof(struct mfi_mpi2_request_raid_scsi_io, 828 SGL) / 4; 829 io_req->ChainOffset = sc->chain_offset_value_for_mpt_ptmsg; 830 831 mpi25_ieee_chain->Address = mfi_cmd->cm_frame_busaddr; 832 833 /* 834 In MFI pass thru, nextChainOffset will always be zero to 835 indicate the end of the chain. 836 */ 837 mpi25_ieee_chain->Flags= MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT 838 | MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR; 839 840 /* setting the length to the maximum length */ 841 mpi25_ieee_chain->Length = 1024; 842 843 return 0; 844 } 845 846 void 847 mfi_tbolt_build_ldio(struct mfi_softc *sc, struct mfi_command *mfi_cmd, 848 struct mfi_cmd_tbolt *cmd) 849 { 850 uint32_t start_lba_lo = 0, start_lba_hi = 0, device_id; 851 struct mfi_mpi2_request_raid_scsi_io *io_request; 852 struct IO_REQUEST_INFO io_info; 853 854 device_id = mfi_cmd->cm_frame->io.header.target_id; 855 io_request = cmd->io_request; 856 io_request->RaidContext.TargetID = device_id; 857 io_request->RaidContext.Status = 0; 858 io_request->RaidContext.exStatus =0; 859 860 start_lba_lo = mfi_cmd->cm_frame->io.lba_lo; 861 start_lba_hi = mfi_cmd->cm_frame->io.lba_hi; 862 863 memset(&io_info, 0, sizeof(struct IO_REQUEST_INFO)); 864 io_info.ldStartBlock = ((uint64_t)start_lba_hi << 32) | start_lba_lo; 865 io_info.numBlocks = mfi_cmd->cm_frame->io.header.data_len; 866 io_info.ldTgtId = device_id; 867 if ((mfi_cmd->cm_frame->header.flags & MFI_FRAME_DIR_READ) == 868 MFI_FRAME_DIR_READ) 869 io_info.isRead = 1; 870 871 io_request->RaidContext.timeoutValue = MFI_FUSION_FP_DEFAULT_TIMEOUT; 872 io_request->Function = MPI2_FUNCTION_LD_IO_REQUEST; 873 io_request->DevHandle = device_id; 874 cmd->request_desc->header.RequestFlags = 875 (MFI_REQ_DESCRIPT_FLAGS_LD_IO << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 876 if ((io_request->IoFlags == 6) && (io_info.numBlocks == 0)) 877 io_request->RaidContext.RegLockLength = 0x100; 878 io_request->DataLength = mfi_cmd->cm_frame->io.header.data_len 879 * MFI_SECTOR_LEN; 880 } 881 882 int mfi_tbolt_is_ldio(struct mfi_command *mfi_cmd) 883 { 884 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_READ 885 || mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE) 886 return 1; 887 else 888 return 0; 889 } 890 891 int 892 mfi_tbolt_build_io(struct mfi_softc *sc, struct mfi_command *mfi_cmd, struct mfi_cmd_tbolt *cmd) 893 { 894 uint32_t sge_count; 895 uint8_t cdb[32], cdb_len; 896 897 memset(cdb, 0, 32); 898 struct mfi_mpi2_request_raid_scsi_io *io_request = cmd->io_request; 899 900 /* Have to build CDB here for TB as BSD don't have a scsi layer */ 901 if ((cdb_len = mfi_tbolt_build_cdb(sc, mfi_cmd, cdb)) == 1) 902 return 1; 903 904 /* Just the CDB length,rest of the Flags are zero */ 905 io_request->IoFlags = cdb_len; 906 memcpy(io_request->CDB.CDB32, cdb, 32); 907 908 if (mfi_tbolt_is_ldio(mfi_cmd)) 909 mfi_tbolt_build_ldio(sc, mfi_cmd , cmd); 910 else 911 return 1; 912 913 /* 914 * Construct SGL 915 */ 916 sge_count = mfi_tbolt_make_sgl(sc, mfi_cmd, 917 (pMpi25IeeeSgeChain64_t) &io_request->SGL, cmd); 918 if (sge_count > sc->mfi_max_sge) { 919 device_printf(sc->mfi_dev, "Error. sge_count (0x%x) exceeds " 920 "max (0x%x) allowed\n", sge_count, sc->mfi_max_sge); 921 return 1; 922 } 923 io_request->RaidContext.numSGE = sge_count; 924 io_request->SGLFlags = MPI2_SGE_FLAGS_64_BIT_ADDRESSING; 925 926 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE) 927 io_request->Control = MPI2_SCSIIO_CONTROL_WRITE; 928 else 929 io_request->Control = MPI2_SCSIIO_CONTROL_READ; 930 931 io_request->SGLOffset0 = offsetof( 932 struct mfi_mpi2_request_raid_scsi_io, SGL)/4; 933 934 io_request->SenseBufferLowAddress = mfi_cmd->cm_sense_busaddr; 935 io_request->SenseBufferLength = MFI_SENSE_LEN; 936 return 0; 937 } 938 939 static int 940 mfi_tbolt_build_cdb(struct mfi_softc *sc, struct mfi_command *mfi_cmd, 941 uint8_t *cdb) 942 { 943 uint32_t lba_lo, lba_hi, num_lba; 944 uint8_t cdb_len; 945 946 if (mfi_cmd == NULL || cdb == NULL) 947 return 1; 948 num_lba = mfi_cmd->cm_frame->io.header.data_len; 949 lba_lo = mfi_cmd->cm_frame->io.lba_lo; 950 lba_hi = mfi_cmd->cm_frame->io.lba_hi; 951 952 if ((num_lba <= 0xFF) && (lba_lo <= 0x1FFFFF)) { 953 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE) 954 /* Read 6 or Write 6 */ 955 cdb[0] = (uint8_t) (0x0A); 956 else 957 cdb[0] = (uint8_t) (0x08); 958 959 cdb[4] = (uint8_t) num_lba; 960 cdb[3] = (uint8_t) (lba_lo & 0xFF); 961 cdb[2] = (uint8_t) (lba_lo >> 8); 962 cdb[1] = (uint8_t) ((lba_lo >> 16) & 0x1F); 963 cdb_len = 6; 964 } else if ((num_lba <= 0xFFFF) && (lba_lo <= 0xFFFFFFFF)) { 965 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE) 966 /* Read 10 or Write 10 */ 967 cdb[0] = (uint8_t) (0x2A); 968 else 969 cdb[0] = (uint8_t) (0x28); 970 cdb[8] = (uint8_t) (num_lba & 0xFF); 971 cdb[7] = (uint8_t) (num_lba >> 8); 972 cdb[5] = (uint8_t) (lba_lo & 0xFF); 973 cdb[4] = (uint8_t) (lba_lo >> 8); 974 cdb[3] = (uint8_t) (lba_lo >> 16); 975 cdb[2] = (uint8_t) (lba_lo >> 24); 976 cdb_len = 10; 977 } else if ((num_lba > 0xFFFF) && (lba_hi == 0)) { 978 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE) 979 /* Read 12 or Write 12 */ 980 cdb[0] = (uint8_t) (0xAA); 981 else 982 cdb[0] = (uint8_t) (0xA8); 983 cdb[9] = (uint8_t) (num_lba & 0xFF); 984 cdb[8] = (uint8_t) (num_lba >> 8); 985 cdb[7] = (uint8_t) (num_lba >> 16); 986 cdb[6] = (uint8_t) (num_lba >> 24); 987 cdb[5] = (uint8_t) (lba_lo & 0xFF); 988 cdb[4] = (uint8_t) (lba_lo >> 8); 989 cdb[3] = (uint8_t) (lba_lo >> 16); 990 cdb[2] = (uint8_t) (lba_lo >> 24); 991 cdb_len = 12; 992 } else { 993 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE) 994 cdb[0] = (uint8_t) (0x8A); 995 else 996 cdb[0] = (uint8_t) (0x88); 997 cdb[13] = (uint8_t) (num_lba & 0xFF); 998 cdb[12] = (uint8_t) (num_lba >> 8); 999 cdb[11] = (uint8_t) (num_lba >> 16); 1000 cdb[10] = (uint8_t) (num_lba >> 24); 1001 cdb[9] = (uint8_t) (lba_lo & 0xFF); 1002 cdb[8] = (uint8_t) (lba_lo >> 8); 1003 cdb[7] = (uint8_t) (lba_lo >> 16); 1004 cdb[6] = (uint8_t) (lba_lo >> 24); 1005 cdb[5] = (uint8_t) (lba_hi & 0xFF); 1006 cdb[4] = (uint8_t) (lba_hi >> 8); 1007 cdb[3] = (uint8_t) (lba_hi >> 16); 1008 cdb[2] = (uint8_t) (lba_hi >> 24); 1009 cdb_len = 16; 1010 } 1011 return cdb_len; 1012 } 1013 1014 static int 1015 mfi_tbolt_make_sgl(struct mfi_softc *sc, struct mfi_command *mfi_cmd, 1016 pMpi25IeeeSgeChain64_t sgl_ptr, struct mfi_cmd_tbolt *cmd) 1017 { 1018 uint8_t i, sg_processed; 1019 uint8_t sge_count, sge_idx; 1020 union mfi_sgl *os_sgl; 1021 1022 /* 1023 * Return 0 if there is no data transfer 1024 */ 1025 if (!mfi_cmd->cm_sg || !mfi_cmd->cm_len) { 1026 device_printf(sc->mfi_dev, "Buffer empty \n"); 1027 return 0; 1028 } 1029 os_sgl = mfi_cmd->cm_sg; 1030 sge_count = mfi_cmd->cm_frame->header.sg_count; 1031 1032 if (sge_count > sc->mfi_max_sge) { 1033 device_printf(sc->mfi_dev, "sgl ptr %p sg_cnt %d \n", 1034 os_sgl, sge_count); 1035 return sge_count; 1036 } 1037 1038 if (sge_count > sc->max_SGEs_in_main_message) 1039 /* One element to store the chain info */ 1040 sge_idx = sc->max_SGEs_in_main_message - 1; 1041 else 1042 sge_idx = sge_count; 1043 1044 for (i = 0; i < sge_idx; i++) { 1045 /* 1046 * For 32bit BSD we are getting 32 bit SGL's from OS 1047 * but FW only take 64 bit SGL's so copying from 32 bit 1048 * SGL's to 64. 1049 */ 1050 if (sc->mfi_flags & MFI_FLAGS_SKINNY) { 1051 sgl_ptr->Length = os_sgl->sg_skinny[i].len; 1052 sgl_ptr->Address = os_sgl->sg_skinny[i].addr; 1053 } else { 1054 sgl_ptr->Length = os_sgl->sg32[i].len; 1055 sgl_ptr->Address = os_sgl->sg32[i].addr; 1056 } 1057 sgl_ptr->Flags = 0; 1058 sgl_ptr++; 1059 cmd->io_request->ChainOffset = 0; 1060 } 1061 1062 sg_processed = i; 1063 1064 if (sg_processed < sge_count) { 1065 pMpi25IeeeSgeChain64_t sg_chain; 1066 cmd->io_request->ChainOffset = 1067 sc->chain_offset_value_for_main_message; 1068 sg_chain = sgl_ptr; 1069 /* Prepare chain element */ 1070 sg_chain->NextChainOffset = 0; 1071 sg_chain->Flags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | 1072 MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR); 1073 sg_chain->Length = (sizeof(MPI2_SGE_IO_UNION) * 1074 (sge_count - sg_processed)); 1075 sg_chain->Address = cmd->sg_frame_phys_addr; 1076 sgl_ptr = (pMpi25IeeeSgeChain64_t)cmd->sg_frame; 1077 for (; i < sge_count; i++) { 1078 if (sc->mfi_flags & MFI_FLAGS_SKINNY) { 1079 sgl_ptr->Length = os_sgl->sg_skinny[i].len; 1080 sgl_ptr->Address = os_sgl->sg_skinny[i].addr; 1081 } else { 1082 sgl_ptr->Length = os_sgl->sg32[i].len; 1083 sgl_ptr->Address = os_sgl->sg32[i].addr; 1084 } 1085 sgl_ptr->Flags = 0; 1086 sgl_ptr++; 1087 } 1088 } 1089 return sge_count; 1090 } 1091 1092 union mfi_mpi2_request_descriptor * 1093 mfi_build_and_issue_cmd(struct mfi_softc *sc, struct mfi_command *mfi_cmd) 1094 { 1095 struct mfi_cmd_tbolt *cmd; 1096 union mfi_mpi2_request_descriptor *req_desc = NULL; 1097 uint16_t index; 1098 cmd = mfi_tbolt_get_cmd(sc); 1099 if (!cmd) 1100 return NULL; 1101 mfi_cmd->cm_extra_frames = cmd->index; 1102 cmd->sync_cmd_idx = mfi_cmd->cm_index; 1103 1104 index = cmd->index; 1105 req_desc = mfi_tbolt_get_request_descriptor(sc, index-1); 1106 if (mfi_tbolt_build_io(sc, mfi_cmd, cmd)) 1107 return NULL; 1108 req_desc->header.SMID = index; 1109 return req_desc; 1110 } 1111 1112 union mfi_mpi2_request_descriptor * 1113 mfi_tbolt_build_mpt_cmd(struct mfi_softc *sc, struct mfi_command *cmd) 1114 { 1115 union mfi_mpi2_request_descriptor *req_desc = NULL; 1116 uint16_t index; 1117 if (mfi_build_mpt_pass_thru(sc, cmd)) { 1118 device_printf(sc->mfi_dev, "Couldn't build MFI pass thru " 1119 "cmd\n"); 1120 return NULL; 1121 } 1122 /* For fusion the frame_count variable is used for SMID */ 1123 index = cmd->cm_extra_frames; 1124 1125 req_desc = mfi_tbolt_get_request_descriptor(sc, index - 1); 1126 if (!req_desc) 1127 return NULL; 1128 1129 bzero(req_desc, sizeof(*req_desc)); 1130 req_desc->header.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << 1131 MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); 1132 req_desc->header.SMID = index; 1133 return req_desc; 1134 } 1135 1136 int 1137 mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm) 1138 { 1139 struct mfi_frame_header *hdr; 1140 uint8_t *cdb; 1141 union mfi_mpi2_request_descriptor *req_desc = NULL; 1142 int tm = MFI_POLL_TIMEOUT_SECS * 1000; 1143 1144 hdr = &cm->cm_frame->header; 1145 cdb = cm->cm_frame->pass.cdb; 1146 if (sc->adpreset) 1147 return 1; 1148 if ((cm->cm_flags & MFI_CMD_POLLED) == 0) { 1149 cm->cm_timestamp = time_uptime; 1150 mfi_enqueue_busy(cm); 1151 } 1152 else { 1153 hdr->cmd_status = 0xff; 1154 hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE; 1155 } 1156 1157 if (hdr->cmd == MFI_CMD_PD_SCSI_IO) { 1158 /* check for inquiry commands coming from CLI */ 1159 if (cdb[0] != 0x28 || cdb[0] != 0x2A) { 1160 if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == 1161 NULL) { 1162 device_printf(sc->mfi_dev, "Mapping from MFI " 1163 "to MPT Failed \n"); 1164 return 1; 1165 } 1166 } 1167 else 1168 device_printf(sc->mfi_dev, "DJA NA XXX SYSPDIO\n"); 1169 } 1170 else if (hdr->cmd == MFI_CMD_LD_SCSI_IO || 1171 hdr->cmd == MFI_CMD_LD_READ || hdr->cmd == MFI_CMD_LD_WRITE) { 1172 if ((req_desc = mfi_build_and_issue_cmd(sc, cm)) == NULL) { 1173 device_printf(sc->mfi_dev, "LDIO Failed \n"); 1174 return 1; 1175 } 1176 } else 1177 if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) { 1178 device_printf(sc->mfi_dev, "Mapping from MFI to MPT " 1179 "Failed\n"); 1180 return 1; 1181 } 1182 MFI_WRITE4(sc, MFI_ILQP, (req_desc->words & 0xFFFFFFFF)); 1183 MFI_WRITE4(sc, MFI_IHQP, (req_desc->words >>0x20)); 1184 1185 if ((cm->cm_flags & MFI_CMD_POLLED) == 0) 1186 return 0; 1187 1188 /* This is a polled command, so busy-wait for it to complete. */ 1189 while (hdr->cmd_status == 0xff) { 1190 DELAY(1000); 1191 tm -= 1; 1192 if (tm <= 0) 1193 break; 1194 } 1195 1196 if (hdr->cmd_status == 0xff) { 1197 device_printf(sc->mfi_dev, "Frame %p timed out " 1198 "command 0x%X\n", hdr, cm->cm_frame->dcmd.opcode); 1199 return (ETIMEDOUT); 1200 } 1201 return 0; 1202 } 1203 1204 static void mfi_issue_pending_cmds_again (struct mfi_softc *sc) 1205 { 1206 struct mfi_command *cm, *tmp; 1207 1208 mfi_lockassert(&sc->mfi_io_lock); 1209 TAILQ_FOREACH_REVERSE_MUTABLE(cm, &sc->mfi_busy, BUSYQ, cm_link, tmp) { 1210 1211 cm->retry_for_fw_reset++; 1212 1213 /* 1214 * If a command has continuously been tried multiple times 1215 * and causing a FW reset condition, no further recoveries 1216 * should be performed on the controller 1217 */ 1218 if (cm->retry_for_fw_reset == 3) { 1219 device_printf(sc->mfi_dev, "megaraid_sas: command %d " 1220 "was tried multiple times during adapter reset" 1221 "Shutting down the HBA\n", cm->cm_index); 1222 mfi_kill_hba(sc); 1223 sc->hw_crit_error = 1; 1224 return; 1225 } 1226 1227 if ((cm->cm_flags & MFI_ON_MFIQ_BUSY) != 0) { 1228 struct mfi_cmd_tbolt *cmd; 1229 mfi_remove_busy(cm); 1230 cmd = sc->mfi_cmd_pool_tbolt[cm->cm_extra_frames - 1231 1 ]; 1232 mfi_tbolt_return_cmd(sc, cmd); 1233 if ((cm->cm_flags & MFI_ON_MFIQ_MASK) == 0) { 1234 if (cm->cm_frame->dcmd.opcode != 1235 MFI_DCMD_CTRL_EVENT_WAIT) { 1236 device_printf(sc->mfi_dev, 1237 "APJ ****requeue command %d \n", 1238 cm->cm_index); 1239 mfi_requeue_ready(cm); 1240 } 1241 } 1242 else 1243 mfi_release_command(cm); 1244 } 1245 } 1246 mfi_startio(sc); 1247 } 1248 1249 static void mfi_kill_hba (struct mfi_softc *sc) 1250 { 1251 if (sc->mfi_flags & MFI_FLAGS_TBOLT) 1252 MFI_WRITE4 (sc, 0x00,MFI_STOP_ADP); 1253 else 1254 MFI_WRITE4 (sc, MFI_IDB,MFI_STOP_ADP); 1255 } 1256 1257 static void mfi_process_fw_state_chg_isr(void *arg) 1258 { 1259 struct mfi_softc *sc= (struct mfi_softc *)arg; 1260 struct mfi_cmd_tbolt *cmd; 1261 int error, status; 1262 1263 if (sc->adpreset == 1) { 1264 device_printf(sc->mfi_dev, "First stage of FW reset " 1265 "initiated...\n"); 1266 1267 sc->mfi_adp_reset(sc); 1268 sc->mfi_enable_intr(sc); 1269 1270 device_printf(sc->mfi_dev, "First stage of reset complete, " 1271 "second stage initiated...\n"); 1272 1273 sc->adpreset = 2; 1274 1275 /* waiting for about 20 second before start the second init */ 1276 for (int wait = 0; wait < 20000; wait++) 1277 DELAY(1000); 1278 device_printf(sc->mfi_dev, "Second stage of FW reset " 1279 "initiated...\n"); 1280 while ((status = MFI_READ4(sc, MFI_RSR)) & 0x04); 1281 1282 sc->mfi_disable_intr(sc); 1283 1284 /* We expect the FW state to be READY */ 1285 if (mfi_transition_firmware(sc)) { 1286 device_printf(sc->mfi_dev, "controller is not in " 1287 "ready state\n"); 1288 mfi_kill_hba(sc); 1289 sc->hw_crit_error= 1; 1290 return ; 1291 } 1292 if ((error = mfi_tbolt_init_MFI_queue(sc)) != 0) 1293 return; 1294 1295 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE); 1296 1297 sc->mfi_enable_intr(sc); 1298 sc->adpreset = 0; 1299 kfree(sc->mfi_aen_cm->cm_data, M_MFIBUF); 1300 mfi_remove_busy(sc->mfi_aen_cm); 1301 cmd = sc->mfi_cmd_pool_tbolt[sc->mfi_aen_cm->cm_extra_frames 1302 - 1]; 1303 mfi_tbolt_return_cmd(sc, cmd); 1304 if (sc->mfi_aen_cm) { 1305 mfi_release_command(sc->mfi_aen_cm); 1306 sc->mfi_aen_cm = NULL; 1307 } 1308 if (sc->map_update_cmd) { 1309 mfi_release_command(sc->map_update_cmd); 1310 sc->map_update_cmd = NULL; 1311 } 1312 mfi_issue_pending_cmds_again(sc); 1313 1314 /* 1315 * Issue pending command can result in adapter being marked 1316 * dead because of too many re-tries. Check for that 1317 * condition before clearing the reset condition on the FW 1318 */ 1319 if (!sc->hw_crit_error) { 1320 /* 1321 * Initiate AEN (Asynchronous Event Notification) 1322 */ 1323 mfi_aen_setup(sc, sc->last_seq_num); 1324 sc->issuepend_done = 1; 1325 device_printf(sc->mfi_dev, "second stage of reset " 1326 "complete, FW is ready now.\n"); 1327 } else { 1328 device_printf(sc->mfi_dev, "second stage of reset " 1329 "never completed, hba was marked offline.\n"); 1330 } 1331 } else { 1332 device_printf(sc->mfi_dev, "mfi_process_fw_state_chg_isr " 1333 "called with unhandled value:%d\n", sc->adpreset); 1334 } 1335 lockmgr(&sc->mfi_io_lock, LK_RELEASE); 1336 } 1337