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