mfi(4): Update to LSI's version 4.23 of the driver.
[dragonfly.git] / sys / dev / raid / mfi / mfi_tbolt.c
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_second;
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_second;
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((void *) 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         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
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         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
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
872                      = MFI_FUSION_FP_DEFAULT_TIMEOUT;
873                 io_request->Function = MPI2_FUNCTION_LD_IO_REQUEST;
874                 io_request->DevHandle = device_id;
875                 cmd->request_desc->header.RequestFlags
876                     = (MFI_REQ_DESCRIPT_FLAGS_LD_IO
877                     << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
878         if ((io_request->IoFlags == 6) && (io_info.numBlocks == 0))
879                 io_request->RaidContext.RegLockLength = 0x100;
880         io_request->DataLength = mfi_cmd->cm_frame->io.header.data_len
881             * MFI_SECTOR_LEN;
882 }
883
884 int mfi_tbolt_is_ldio(struct mfi_command *mfi_cmd)
885 {
886         if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_READ
887             || mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
888                 return 1;
889         else
890                 return 0;
891 }
892
893 int
894 mfi_tbolt_build_io(struct mfi_softc *sc, struct mfi_command *mfi_cmd, struct mfi_cmd_tbolt *cmd)
895 {
896         uint32_t device_id;
897         uint32_t sge_count;
898         uint8_t cdb[32], cdb_len;
899
900         memset(cdb, 0, 32);
901         struct mfi_mpi2_request_raid_scsi_io *io_request = cmd->io_request;
902
903         device_id = mfi_cmd->cm_frame->header.target_id;
904
905         /* Have to build CDB here for TB as BSD don't have a scsi layer */
906         if ((cdb_len = mfi_tbolt_build_cdb(sc, mfi_cmd, cdb)) == 1)
907                 return 1;
908
909         /* Just the CDB length,rest of the Flags are zero */
910         io_request->IoFlags = cdb_len;
911         memcpy(io_request->CDB.CDB32, cdb, 32);
912
913         if (mfi_tbolt_is_ldio(mfi_cmd))
914                 mfi_tbolt_build_ldio(sc, mfi_cmd , cmd);
915         else
916                 return 1;
917
918         /*
919          * Construct SGL
920          */
921         sge_count = mfi_tbolt_make_sgl(sc, mfi_cmd,
922             (pMpi25IeeeSgeChain64_t) &io_request->SGL, cmd);
923         if (sge_count > sc->mfi_max_sge) {
924                 device_printf(sc->mfi_dev, "Error. sge_count (0x%x) exceeds "
925                     "max (0x%x) allowed\n", sge_count, sc->mfi_max_sge);
926                 return 1;
927         }
928         io_request->RaidContext.numSGE = sge_count;
929         io_request->SGLFlags = MPI2_SGE_FLAGS_64_BIT_ADDRESSING;
930
931         if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
932                 io_request->Control = MPI2_SCSIIO_CONTROL_WRITE;
933         else
934                 io_request->Control = MPI2_SCSIIO_CONTROL_READ;
935
936         io_request->SGLOffset0 = offsetof(
937             struct mfi_mpi2_request_raid_scsi_io, SGL)/4;
938
939         io_request->SenseBufferLowAddress = mfi_cmd->cm_sense_busaddr;
940         io_request->SenseBufferLength = MFI_SENSE_LEN;
941         return 0;
942 }
943
944 static int
945 mfi_tbolt_build_cdb(struct mfi_softc *sc, struct mfi_command *mfi_cmd,
946     uint8_t *cdb)
947 {
948         uint32_t lba_lo, lba_hi, num_lba;
949         uint8_t cdb_len;
950
951         if (mfi_cmd == NULL || cdb == NULL)
952                 return 1;
953         num_lba = mfi_cmd->cm_frame->io.header.data_len;
954         lba_lo = mfi_cmd->cm_frame->io.lba_lo;
955         lba_hi = mfi_cmd->cm_frame->io.lba_hi;
956
957         if ((num_lba <= 0xFF) && (lba_lo <= 0x1FFFFF)) {
958                 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
959                         /* Read 6 or Write 6 */
960                         cdb[0] = (uint8_t) (0x0A);
961                 else
962                         cdb[0] = (uint8_t) (0x08);
963
964                 cdb[4] = (uint8_t) num_lba;
965                 cdb[3] = (uint8_t) (lba_lo & 0xFF);
966                 cdb[2] = (uint8_t) (lba_lo >> 8);
967                 cdb[1] = (uint8_t) ((lba_lo >> 16) & 0x1F);
968                 cdb_len = 6;
969         } else if ((num_lba <= 0xFFFF) && (lba_lo <= 0xFFFFFFFF)) {
970                 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
971                         /* Read 10 or Write 10 */
972                         cdb[0] = (uint8_t) (0x2A);
973                 else
974                         cdb[0] = (uint8_t) (0x28);
975                 cdb[8] = (uint8_t) (num_lba & 0xFF);
976                 cdb[7] = (uint8_t) (num_lba >> 8);
977                 cdb[5] = (uint8_t) (lba_lo & 0xFF);
978                 cdb[4] = (uint8_t) (lba_lo >> 8);
979                 cdb[3] = (uint8_t) (lba_lo >> 16);
980                 cdb[2] = (uint8_t) (lba_lo >> 24);
981                 cdb_len = 10;
982         } else if ((num_lba > 0xFFFF) && (lba_hi == 0)) {
983                 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
984                         /* Read 12 or Write 12 */
985                         cdb[0] = (uint8_t) (0xAA);
986                 else
987                         cdb[0] = (uint8_t) (0xA8);
988                 cdb[9] = (uint8_t) (num_lba & 0xFF);
989                 cdb[8] = (uint8_t) (num_lba >> 8);
990                 cdb[7] = (uint8_t) (num_lba >> 16);
991                 cdb[6] = (uint8_t) (num_lba >> 24);
992                 cdb[5] = (uint8_t) (lba_lo & 0xFF);
993                 cdb[4] = (uint8_t) (lba_lo >> 8);
994                 cdb[3] = (uint8_t) (lba_lo >> 16);
995                 cdb[2] = (uint8_t) (lba_lo >> 24);
996                 cdb_len = 12;
997         } else {
998                 if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)
999                         cdb[0] = (uint8_t) (0x8A);
1000                 else
1001                         cdb[0] = (uint8_t) (0x88);
1002                 cdb[13] = (uint8_t) (num_lba & 0xFF);
1003                 cdb[12] = (uint8_t) (num_lba >> 8);
1004                 cdb[11] = (uint8_t) (num_lba >> 16);
1005                 cdb[10] = (uint8_t) (num_lba >> 24);
1006                 cdb[9] = (uint8_t) (lba_lo & 0xFF);
1007                 cdb[8] = (uint8_t) (lba_lo >> 8);
1008                 cdb[7] = (uint8_t) (lba_lo >> 16);
1009                 cdb[6] = (uint8_t) (lba_lo >> 24);
1010                 cdb[5] = (uint8_t) (lba_hi & 0xFF);
1011                 cdb[4] = (uint8_t) (lba_hi >> 8);
1012                 cdb[3] = (uint8_t) (lba_hi >> 16);
1013                 cdb[2] = (uint8_t) (lba_hi >> 24);
1014                 cdb_len = 16;
1015         }
1016         return cdb_len;
1017 }
1018
1019 static int
1020 mfi_tbolt_make_sgl(struct mfi_softc *sc, struct mfi_command *mfi_cmd,
1021                    pMpi25IeeeSgeChain64_t sgl_ptr, struct mfi_cmd_tbolt *cmd)
1022 {
1023         uint8_t i, sg_processed, sg_to_process;
1024         uint8_t sge_count, sge_idx;
1025         union mfi_sgl *os_sgl;
1026
1027         /*
1028          * Return 0 if there is no data transfer
1029          */
1030         if (!mfi_cmd->cm_sg || !mfi_cmd->cm_len) {
1031                 device_printf(sc->mfi_dev, "Buffer empty \n");
1032                 return 0;
1033         }
1034         os_sgl = mfi_cmd->cm_sg;
1035         sge_count = mfi_cmd->cm_frame->header.sg_count;
1036
1037         if (sge_count > sc->mfi_max_sge) {
1038                 device_printf(sc->mfi_dev, "sgl ptr %p sg_cnt %d \n",
1039                     os_sgl, sge_count);
1040                 return sge_count;
1041         }
1042
1043         if (sge_count > sc->max_SGEs_in_main_message)
1044                 /* One element to store the chain info */
1045                 sge_idx = sc->max_SGEs_in_main_message - 1;
1046         else
1047                 sge_idx = sge_count;
1048
1049         for (i = 0; i < sge_idx; i++) {
1050                 /*
1051                  * For 32bit BSD we are getting 32 bit SGL's from OS
1052                  * but FW only take 64 bit SGL's so copying from 32 bit
1053                  * SGL's to 64.
1054                  */
1055                 if (sc->mfi_flags & MFI_FLAGS_SKINNY) {
1056                         sgl_ptr->Length = os_sgl->sg_skinny[i].len;
1057                         sgl_ptr->Address = os_sgl->sg_skinny[i].addr;
1058                 } else {
1059                         sgl_ptr->Length = os_sgl->sg32[i].len;
1060                         sgl_ptr->Address = os_sgl->sg32[i].addr;
1061                 }
1062                 sgl_ptr->Flags = 0;
1063                 sgl_ptr++;
1064                 cmd->io_request->ChainOffset = 0;
1065         }
1066
1067         sg_processed = i;
1068
1069         if (sg_processed < sge_count) {
1070                 pMpi25IeeeSgeChain64_t sg_chain;
1071                 sg_to_process = sge_count - sg_processed;
1072                 cmd->io_request->ChainOffset =
1073                     sc->chain_offset_value_for_main_message;
1074                 sg_chain = sgl_ptr;
1075                 /* Prepare chain element */
1076                 sg_chain->NextChainOffset = 0;
1077                 sg_chain->Flags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
1078                     MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR);
1079                 sg_chain->Length =  (sizeof(MPI2_SGE_IO_UNION) *
1080                     (sge_count - sg_processed));
1081                 sg_chain->Address = cmd->sg_frame_phys_addr;
1082                 sgl_ptr = (pMpi25IeeeSgeChain64_t)cmd->sg_frame;
1083                 for (; i < sge_count; i++) {
1084                         if (sc->mfi_flags & MFI_FLAGS_SKINNY) {
1085                                 sgl_ptr->Length = os_sgl->sg_skinny[i].len;
1086                                 sgl_ptr->Address = os_sgl->sg_skinny[i].addr;
1087                         } else {
1088                                 sgl_ptr->Length = os_sgl->sg32[i].len;
1089                                 sgl_ptr->Address = os_sgl->sg32[i].addr;
1090                         }
1091                         sgl_ptr->Flags = 0;
1092                         sgl_ptr++;
1093                 }
1094         }
1095         return sge_count;
1096 }
1097
1098 union mfi_mpi2_request_descriptor *
1099 mfi_build_and_issue_cmd(struct mfi_softc *sc, struct mfi_command *mfi_cmd)
1100 {
1101         struct mfi_cmd_tbolt *cmd;
1102         union mfi_mpi2_request_descriptor *req_desc = NULL;
1103         uint16_t index;
1104         cmd = mfi_tbolt_get_cmd(sc);
1105         if (!cmd)
1106                 return NULL;
1107         mfi_cmd->cm_extra_frames = cmd->index;
1108         cmd->sync_cmd_idx = mfi_cmd->cm_index;
1109
1110         index = cmd->index;
1111         req_desc = mfi_tbolt_get_request_descriptor(sc, index-1);
1112         if (mfi_tbolt_build_io(sc, mfi_cmd, cmd))
1113                 return NULL;
1114         req_desc->header.SMID = index;
1115         return req_desc;
1116 }
1117
1118 union mfi_mpi2_request_descriptor *
1119 mfi_tbolt_build_mpt_cmd(struct mfi_softc *sc, struct mfi_command *cmd)
1120 {
1121         union mfi_mpi2_request_descriptor *req_desc = NULL;
1122         uint16_t index;
1123         if (mfi_build_mpt_pass_thru(sc, cmd)) {
1124                 device_printf(sc->mfi_dev, "Couldn't build MFI pass thru "
1125                     "cmd\n");
1126                 return NULL;
1127         }
1128         /* For fusion the frame_count variable is used for SMID */
1129         index = cmd->cm_extra_frames;
1130
1131         req_desc = mfi_tbolt_get_request_descriptor(sc, index - 1);
1132         if (!req_desc)
1133                 return NULL;
1134
1135         bzero(req_desc, sizeof(req_desc));
1136         req_desc->header.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
1137             MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
1138         req_desc->header.SMID = index;
1139         return req_desc;
1140 }
1141
1142 int
1143 mfi_tbolt_send_frame(struct mfi_softc *sc, struct mfi_command *cm)
1144 {
1145         struct mfi_frame_header *hdr;
1146         uint8_t *cdb;
1147         union mfi_mpi2_request_descriptor *req_desc = NULL;
1148         int tm = MFI_POLL_TIMEOUT_SECS * 1000;
1149
1150         hdr = &cm->cm_frame->header;
1151         cdb = cm->cm_frame->pass.cdb;
1152         if (sc->adpreset)
1153                 return 1;
1154         if ((cm->cm_flags & MFI_CMD_POLLED) == 0) {
1155                 cm->cm_timestamp = time_second;
1156                 mfi_enqueue_busy(cm);
1157         }
1158         else {
1159                 hdr->cmd_status = 0xff;
1160                 hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
1161         }
1162
1163         if (hdr->cmd == MFI_CMD_PD_SCSI_IO) {
1164                 /* check for inquiry commands coming from CLI */
1165                 if (cdb[0] != 0x28 || cdb[0] != 0x2A) {
1166                         if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) ==
1167                             NULL) {
1168                                 device_printf(sc->mfi_dev, "Mapping from MFI "
1169                                     "to MPT Failed \n");
1170                                 return 1;
1171                         }
1172                 }
1173                 else
1174                         device_printf(sc->mfi_dev, "DJA NA XXX SYSPDIO\n");
1175         }
1176         else if (hdr->cmd == MFI_CMD_LD_SCSI_IO ||
1177             hdr->cmd == MFI_CMD_LD_READ || hdr->cmd == MFI_CMD_LD_WRITE) {
1178                 if ((req_desc = mfi_build_and_issue_cmd(sc, cm)) == NULL) {
1179                         device_printf(sc->mfi_dev, "LDIO Failed \n");
1180                         return 1;
1181                 }
1182         } else
1183                 if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) {
1184                         device_printf(sc->mfi_dev, "Mapping from MFI to MPT "
1185                             "Failed\n");
1186                         return 1;
1187                 }
1188         MFI_WRITE4(sc, MFI_ILQP, (req_desc->words & 0xFFFFFFFF));
1189         MFI_WRITE4(sc, MFI_IHQP, (req_desc->words >>0x20));
1190
1191         if ((cm->cm_flags & MFI_CMD_POLLED) == 0)
1192                 return 0;
1193
1194         /* This is a polled command, so busy-wait for it to complete. */
1195         while (hdr->cmd_status == 0xff) {
1196                 DELAY(1000);
1197                 tm -= 1;
1198                 if (tm <= 0)
1199                         break;
1200         }
1201
1202         if (hdr->cmd_status == 0xff) {
1203                 device_printf(sc->mfi_dev, "Frame %p timed out "
1204                       "command 0x%X\n", hdr, cm->cm_frame->dcmd.opcode);
1205                 return (ETIMEDOUT);
1206         }
1207         return 0;
1208 }
1209
1210 static void mfi_issue_pending_cmds_again (struct mfi_softc *sc)
1211 {
1212         struct mfi_command *cm, *tmp;
1213
1214         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1215         TAILQ_FOREACH_REVERSE_MUTABLE(cm, &sc->mfi_busy, BUSYQ, cm_link, tmp) {
1216
1217                 cm->retry_for_fw_reset++;
1218
1219                 /*
1220                  * If a command has continuously been tried multiple times
1221                  * and causing a FW reset condition, no further recoveries
1222                  * should be performed on the controller
1223                  */
1224                 if (cm->retry_for_fw_reset == 3) {
1225                         device_printf(sc->mfi_dev, "megaraid_sas: command %d "
1226                             "was tried multiple times during adapter reset"
1227                             "Shutting down the HBA\n", cm->cm_index);
1228                         mfi_kill_hba(sc);
1229                         sc->hw_crit_error = 1;
1230                         return;
1231                 }
1232
1233                 if ((cm->cm_flags & MFI_ON_MFIQ_BUSY) != 0) {
1234                         struct mfi_cmd_tbolt *cmd;
1235                         mfi_remove_busy(cm);
1236                         cmd = sc->mfi_cmd_pool_tbolt[cm->cm_extra_frames -
1237                             1 ];
1238                         mfi_tbolt_return_cmd(sc, cmd);
1239                         if ((cm->cm_flags & MFI_ON_MFIQ_MASK) == 0) {
1240                                 if (cm->cm_frame->dcmd.opcode !=
1241                                     MFI_DCMD_CTRL_EVENT_WAIT) {
1242                                         device_printf(sc->mfi_dev,
1243                                             "APJ ****requeue command %d \n",
1244                                             cm->cm_index);
1245                                         mfi_requeue_ready(cm);
1246                                 }
1247                         }
1248                         else
1249                                 mfi_release_command(cm);
1250                 }
1251         }
1252         mfi_startio(sc);
1253 }
1254
1255 static void mfi_kill_hba (struct mfi_softc *sc)
1256 {
1257         if (sc->mfi_flags & MFI_FLAGS_TBOLT)
1258                 MFI_WRITE4 (sc, 0x00,MFI_STOP_ADP);
1259         else
1260                 MFI_WRITE4 (sc, MFI_IDB,MFI_STOP_ADP);
1261 }
1262
1263 static void mfi_process_fw_state_chg_isr(void *arg)
1264 {
1265         struct mfi_softc *sc= (struct mfi_softc *)arg;
1266         struct mfi_cmd_tbolt *cmd;
1267         int error, status;
1268
1269         if (sc->adpreset == 1) {
1270                 device_printf(sc->mfi_dev, "First stage of FW reset "
1271                      "initiated...\n");
1272
1273                 sc->mfi_adp_reset(sc);
1274                 sc->mfi_enable_intr(sc);
1275
1276                 device_printf(sc->mfi_dev, "First stage of reset complete, "
1277                     "second stage initiated...\n");
1278
1279                 sc->adpreset = 2;
1280
1281                 /* waiting for about 20 second before start the second init */
1282                 for (int wait = 0; wait < 20000; wait++)
1283                         DELAY(1000);
1284                 device_printf(sc->mfi_dev, "Second stage of FW reset "
1285                      "initiated...\n");
1286                 while ((status = MFI_READ4(sc, MFI_RSR)) & 0x04);
1287
1288                 sc->mfi_disable_intr(sc);
1289
1290                 /* We expect the FW state to be READY */
1291                 if (mfi_transition_firmware(sc)) {
1292                         device_printf(sc->mfi_dev, "controller is not in "
1293                             "ready state\n");
1294                         mfi_kill_hba(sc);
1295                         sc->hw_crit_error= 1;
1296                         return ;
1297                 }
1298                 if ((error = mfi_tbolt_init_MFI_queue(sc)) != 0)
1299                                 return;
1300
1301                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1302
1303                 sc->mfi_enable_intr(sc);
1304                 sc->adpreset = 0;
1305                 kfree(sc->mfi_aen_cm->cm_data, M_MFIBUF);
1306                 mfi_remove_busy(sc->mfi_aen_cm);
1307                 cmd = sc->mfi_cmd_pool_tbolt[sc->mfi_aen_cm->cm_extra_frames
1308                     - 1];
1309                 mfi_tbolt_return_cmd(sc, cmd);
1310                 if (sc->mfi_aen_cm) {
1311                         mfi_release_command(sc->mfi_aen_cm);
1312                         sc->mfi_aen_cm = NULL;
1313                 }
1314                 if (sc->map_update_cmd) {
1315                         mfi_release_command(sc->map_update_cmd);
1316                         sc->map_update_cmd = NULL;
1317                 }
1318                 mfi_issue_pending_cmds_again(sc);
1319
1320                 /*
1321                  * Issue pending command can result in adapter being marked
1322                  * dead because of too many re-tries. Check for that
1323                  * condition before clearing the reset condition on the FW
1324                  */
1325                 if (!sc->hw_crit_error) {
1326                         /*
1327                          * Initiate AEN (Asynchronous Event Notification)
1328                          */
1329                         mfi_aen_setup(sc, sc->last_seq_num);
1330                         sc->issuepend_done = 1;
1331                         device_printf(sc->mfi_dev, "second stage of reset "
1332                             "complete, FW is ready now.\n");
1333                 } else {
1334                         device_printf(sc->mfi_dev, "second stage of reset "
1335                              "never completed, hba was marked offline.\n");
1336                 }
1337         } else {
1338                 device_printf(sc->mfi_dev, "mfi_process_fw_state_chg_isr "
1339                     "called with unhandled value:%d\n", sc->adpreset);
1340         }
1341         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1342 }