Merge branch 'vendor/OPENSSL'
[dragonfly.git] / sys / dev / raid / mfi / mfi.c
1 /*-
2  * Copyright (c) 2006 IronPort Systems
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 /*-
27  * Copyright (c) 2007 LSI Corp.
28  * Copyright (c) 2007 Rajesh Prabhakaran.
29  * All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  * 1. Redistributions of source code must retain the above copyright
35  *    notice, this list of conditions and the following disclaimer.
36  * 2. Redistributions in binary form must reproduce the above copyright
37  *    notice, this list of conditions and the following disclaimer in the
38  *    documentation and/or other materials provided with the distribution.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  */
52 /*-
53  * Redistribution and use in source and binary forms, with or without
54  * modification, are permitted provided that the following conditions
55  * are met:
56  *
57  *            Copyright 1994-2009 The FreeBSD Project.
58  *            All rights reserved.
59  *
60  * 1. Redistributions of source code must retain the above copyright
61  *    notice, this list of conditions and the following disclaimer.
62  * 2. Redistributions in binary form must reproduce the above copyright
63  *    notice, this list of conditions and the following disclaimer in the
64  *    documentation and/or other materials provided with the distribution.
65  *
66  *    THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT``AS IS'' AND
67  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
68  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
69  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FREEBSD PROJECT OR
70  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
71  * EXEMPLARY,OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
72  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
73  * PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY
74  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
75  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77  *
78  * The views and conclusions contained in the software and documentation
79  * are those of the authors and should not be interpreted as representing
80  * official policies,either expressed or implied, of the FreeBSD Project.
81  *
82  * $FreeBSD: src/sys/dev/mfi/mfi.c,v 1.62 2011/11/09 21:53:49 delphij Exp $
83  */
84
85 #include "opt_mfi.h"
86
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/sysctl.h>
90 #include <sys/malloc.h>
91 #include <sys/kernel.h>
92 #include <sys/bus.h>
93 #include <sys/eventhandler.h>
94 #include <sys/rman.h>
95 #include <sys/bus_dma.h>
96 #include <sys/buf2.h>
97 #include <sys/uio.h>
98 #include <sys/proc.h>
99 #include <sys/signalvar.h>
100 #include <sys/device.h>
101 #include <sys/mplock2.h>
102
103 #include <bus/cam/scsi/scsi_all.h>
104
105 #include <bus/pci/pcivar.h>
106
107 #include <dev/raid/mfi/mfireg.h>
108 #include <dev/raid/mfi/mfi_ioctl.h>
109 #include <dev/raid/mfi/mfivar.h>
110
111 static int      mfi_alloc_commands(struct mfi_softc *);
112 static int      mfi_comms_init(struct mfi_softc *);
113 static int      mfi_wait_command(struct mfi_softc *, struct mfi_command *);
114 static int      mfi_get_controller_info(struct mfi_softc *);
115 static int      mfi_get_log_state(struct mfi_softc *,
116                     struct mfi_evt_log_state **);
117 static int      mfi_parse_entries(struct mfi_softc *, int, int);
118 static int      mfi_dcmd_command(struct mfi_softc *, struct mfi_command **,
119                     uint32_t, void **, size_t);
120 static void     mfi_data_cb(void *, bus_dma_segment_t *, int, int);
121 static void     mfi_startup(void *arg);
122 static void     mfi_intr(void *arg);
123 static void     mfi_ldprobe(struct mfi_softc *sc);
124 static void     mfi_syspdprobe(struct mfi_softc *sc);
125 static int      mfi_aen_register(struct mfi_softc *sc, int seq, int locale);
126 static void     mfi_aen_complete(struct mfi_command *);
127 static int      mfi_aen_setup(struct mfi_softc *, uint32_t);
128 static int      mfi_add_ld(struct mfi_softc *sc, int);
129 static void     mfi_add_ld_complete(struct mfi_command *);
130 static int      mfi_add_sys_pd(struct mfi_softc *sc, int);
131 static void     mfi_add_sys_pd_complete(struct mfi_command *);
132 static struct mfi_command * mfi_bio_command(struct mfi_softc *);
133 static void     mfi_bio_complete(struct mfi_command *);
134 static struct mfi_command * mfi_build_ldio(struct mfi_softc *,struct bio*);
135 static struct mfi_command * mfi_build_syspdio(struct mfi_softc *,struct bio*);
136 static int      mfi_mapcmd(struct mfi_softc *, struct mfi_command *);
137 static int      mfi_send_frame(struct mfi_softc *, struct mfi_command *);
138 static void     mfi_complete(struct mfi_softc *, struct mfi_command *);
139 static int      mfi_abort(struct mfi_softc *, struct mfi_command *);
140 static int      mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int);
141 static void     mfi_timeout(void *);
142 static int      mfi_user_command(struct mfi_softc *,
143                     struct mfi_ioc_passthru *);
144 static void     mfi_enable_intr_xscale(struct mfi_softc *sc);
145 static void     mfi_enable_intr_ppc(struct mfi_softc *sc);
146 static int32_t  mfi_read_fw_status_xscale(struct mfi_softc *sc);
147 static int32_t  mfi_read_fw_status_ppc(struct mfi_softc *sc);
148 static int      mfi_check_clear_intr_xscale(struct mfi_softc *sc);
149 static int      mfi_check_clear_intr_ppc(struct mfi_softc *sc);
150 static void     mfi_issue_cmd_xscale(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt);
151 static void     mfi_issue_cmd_ppc(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt);
152 static void     mfi_filter_detach(struct knote *);
153 static int      mfi_filter_read(struct knote *, long);
154 static int      mfi_filter_write(struct knote *, long);
155
156 SYSCTL_NODE(_hw, OID_AUTO, mfi, CTLFLAG_RD, 0, "MFI driver parameters");
157 static int      mfi_event_locale = MFI_EVT_LOCALE_ALL;
158 TUNABLE_INT("hw.mfi.event_locale", &mfi_event_locale);
159 SYSCTL_INT(_hw_mfi, OID_AUTO, event_locale, CTLFLAG_RW, &mfi_event_locale,
160             0, "event message locale");
161
162 static int      mfi_event_class = MFI_EVT_CLASS_INFO;
163 TUNABLE_INT("hw.mfi.event_class", &mfi_event_class);
164 SYSCTL_INT(_hw_mfi, OID_AUTO, event_class, CTLFLAG_RW, &mfi_event_class,
165           0, "event message class");
166
167 static int      mfi_max_cmds = 128;
168 TUNABLE_INT("hw.mfi.max_cmds", &mfi_max_cmds);
169 SYSCTL_INT(_hw_mfi, OID_AUTO, max_cmds, CTLFLAG_RD, &mfi_max_cmds,
170            0, "Max commands");
171
172 static int      mfi_msi_enable = 1;
173 TUNABLE_INT("hw.mfi.msi.enable", &mfi_msi_enable);
174
175 /* Management interface */
176 static d_open_t         mfi_open;
177 static d_close_t        mfi_close;
178 static d_ioctl_t        mfi_ioctl;
179 static d_kqfilter_t     mfi_kqfilter;
180
181 static struct dev_ops mfi_ops = {
182         { "mfi", 0, 0 },
183         .d_open =       mfi_open,
184         .d_close =      mfi_close,
185         .d_ioctl =      mfi_ioctl,
186         .d_kqfilter =   mfi_kqfilter,
187 };
188
189 static struct filterops mfi_read_filterops =
190         { FILTEROP_ISFD, NULL, mfi_filter_detach, mfi_filter_read };
191 static struct filterops mfi_write_filterops =
192         { FILTEROP_ISFD, NULL, mfi_filter_detach, mfi_filter_write };
193
194 MALLOC_DEFINE(M_MFIBUF, "mfibuf", "Buffers for the MFI driver");
195
196 #define MFI_INQ_LENGTH SHORT_INQUIRY_LENGTH
197
198 static void
199 mfi_enable_intr_xscale(struct mfi_softc *sc)
200 {
201         MFI_WRITE4(sc, MFI_OMSK, 0x01);
202 }
203
204 static void
205 mfi_enable_intr_ppc(struct mfi_softc *sc)
206 {
207         if (sc->mfi_flags & MFI_FLAGS_1078) {
208                 MFI_WRITE4(sc, MFI_ODCR0, 0xFFFFFFFF);
209                 MFI_WRITE4(sc, MFI_OMSK, ~MFI_1078_EIM);
210         } else if (sc->mfi_flags & MFI_FLAGS_GEN2) {
211                 MFI_WRITE4(sc, MFI_ODCR0, 0xFFFFFFFF);
212                 MFI_WRITE4(sc, MFI_OMSK, ~MFI_GEN2_EIM);
213         } else if (sc->mfi_flags & MFI_FLAGS_SKINNY) {
214                 MFI_WRITE4(sc, MFI_OMSK, ~0x00000001);
215         } else {
216                 panic("unknown adapter type");
217         }
218 }
219
220 static int32_t
221 mfi_read_fw_status_xscale(struct mfi_softc *sc)
222 {
223         return MFI_READ4(sc, MFI_OMSG0);
224 }
225
226 static int32_t
227 mfi_read_fw_status_ppc(struct mfi_softc *sc)
228 {
229         return MFI_READ4(sc, MFI_OSP0);
230 }
231
232 static int
233 mfi_check_clear_intr_xscale(struct mfi_softc *sc)
234 {
235         int32_t status;
236
237         status = MFI_READ4(sc, MFI_OSTS);
238         if ((status & MFI_OSTS_INTR_VALID) == 0)
239                 return 1;
240
241         MFI_WRITE4(sc, MFI_OSTS, status);
242         return 0;
243 }
244
245 static int
246 mfi_check_clear_intr_ppc(struct mfi_softc *sc)
247 {
248         int32_t status;
249
250         status = MFI_READ4(sc, MFI_OSTS);
251         if (((sc->mfi_flags & MFI_FLAGS_1078) && !(status & MFI_1078_RM)) ||
252             ((sc->mfi_flags & MFI_FLAGS_GEN2) && !(status & MFI_GEN2_RM)) ||
253             ((sc->mfi_flags & MFI_FLAGS_SKINNY) && !(status & MFI_SKINNY_RM)))
254                 return 1;
255
256         if (sc->mfi_flags & MFI_FLAGS_SKINNY)
257                 MFI_WRITE4(sc, MFI_OSTS, status);
258         else
259                 MFI_WRITE4(sc, MFI_ODCR0, status);
260         return 0;
261 }
262
263 static void
264 mfi_issue_cmd_xscale(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt)
265 {
266         MFI_WRITE4(sc, MFI_IQP,(bus_add >>3) | frame_cnt);
267 }
268
269 static void
270 mfi_issue_cmd_ppc(struct mfi_softc *sc,uint32_t bus_add,uint32_t frame_cnt)
271 {
272         if (sc->mfi_flags & MFI_FLAGS_SKINNY) {
273                 MFI_WRITE4(sc, MFI_IQPL, (bus_add | frame_cnt << 1) | 1);
274                 MFI_WRITE4(sc, MFI_IQPH, 0x00000000);
275         } else {
276                 MFI_WRITE4(sc, MFI_IQP, (bus_add | frame_cnt << 1) | 1);
277         }
278 }
279
280 static int
281 mfi_transition_firmware(struct mfi_softc *sc)
282 {
283         uint32_t fw_state, cur_state;
284         int max_wait, i;
285         uint32_t cur_abs_reg_val = 0;
286         uint32_t prev_abs_reg_val = 0;
287         bus_space_handle_t idb;
288
289         cur_abs_reg_val = sc->mfi_read_fw_status(sc);
290         fw_state = cur_abs_reg_val & MFI_FWSTATE_MASK;
291         idb = sc->mfi_flags & MFI_FLAGS_SKINNY ? MFI_SKINNY_IDB : MFI_IDB;
292         while (fw_state != MFI_FWSTATE_READY) {
293                 if (bootverbose)
294                         device_printf(sc->mfi_dev, "Waiting for firmware to "
295                         "become ready\n");
296                 cur_state = fw_state;
297                 switch (fw_state) {
298                 case MFI_FWSTATE_FAULT:
299                         device_printf(sc->mfi_dev, "Firmware fault\n");
300                         return (ENXIO);
301                 case MFI_FWSTATE_WAIT_HANDSHAKE:
302                         MFI_WRITE4(sc, idb, MFI_FWINIT_CLEAR_HANDSHAKE);
303                         max_wait = 2;
304                         break;
305                 case MFI_FWSTATE_OPERATIONAL:
306                         MFI_WRITE4(sc, idb, MFI_FWINIT_READY);
307                         max_wait = 10;
308                         break;
309                 case MFI_FWSTATE_UNDEFINED:
310                 case MFI_FWSTATE_BB_INIT:
311                         max_wait = 2;
312                         break;
313                 case MFI_FWSTATE_FW_INIT:
314                 case MFI_FWSTATE_FLUSH_CACHE:
315                         max_wait = 20;
316                         break;
317                 case MFI_FWSTATE_DEVICE_SCAN:
318                         max_wait = 180; /* wait for 180 seconds */
319                         prev_abs_reg_val = cur_abs_reg_val;
320                         break;
321                 case MFI_FWSTATE_BOOT_MESSAGE_PENDING:
322                         MFI_WRITE4(sc, idb, MFI_FWINIT_HOTPLUG);
323                         max_wait = 10;
324                         break;
325                 default:
326                         device_printf(sc->mfi_dev,"Unknown firmware state %#x\n",
327                             fw_state);
328                         return (ENXIO);
329                 }
330                 for (i = 0; i < (max_wait * 10); i++) {
331                         cur_abs_reg_val = sc->mfi_read_fw_status(sc);
332                         fw_state = cur_abs_reg_val & MFI_FWSTATE_MASK;
333                         if (fw_state == cur_state)
334                                 DELAY(100000);
335                         else
336                                 break;
337                 }
338                 if (fw_state == MFI_FWSTATE_DEVICE_SCAN) {
339                         /* Check the device scanning progress */
340                         if (prev_abs_reg_val != cur_abs_reg_val)
341                                 continue;
342                 }
343                 if (fw_state == cur_state) {
344                         device_printf(sc->mfi_dev, "Firmware stuck in state "
345                             "%#x\n", fw_state);
346                         return (ENXIO);
347                 }
348         }
349         return (0);
350 }
351
352 #if defined(__x86_64__)
353 static void
354 mfi_addr64_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
355 {
356         uint64_t *addr;
357
358         addr = arg;
359         *addr = segs[0].ds_addr;
360 }
361 #else
362 static void
363 mfi_addr32_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
364 {
365         uint32_t *addr;
366
367         addr = arg;
368         *addr = segs[0].ds_addr;
369 }
370 #endif
371
372 int
373 mfi_attach(struct mfi_softc *sc)
374 {
375         uint32_t status;
376         int error, commsz, framessz, sensesz;
377         int frames, unit, max_fw_sge;
378         u_int irq_flags;
379
380         device_printf(sc->mfi_dev, "Megaraid SAS driver Ver 3.981\n");
381
382         lockinit(&sc->mfi_io_lock, "MFI I/O lock", 0, LK_CANRECURSE);
383         lockinit(&sc->mfi_config_lock, "MFI config", 0, LK_CANRECURSE);
384         TAILQ_INIT(&sc->mfi_ld_tqh);
385         TAILQ_INIT(&sc->mfi_syspd_tqh);
386         TAILQ_INIT(&sc->mfi_aen_pids);
387         TAILQ_INIT(&sc->mfi_cam_ccbq);
388
389         mfi_initq_free(sc);
390         mfi_initq_ready(sc);
391         mfi_initq_busy(sc);
392         mfi_initq_bio(sc);
393
394         if (sc->mfi_flags & MFI_FLAGS_1064R) {
395                 sc->mfi_enable_intr = mfi_enable_intr_xscale;
396                 sc->mfi_read_fw_status = mfi_read_fw_status_xscale;
397                 sc->mfi_check_clear_intr = mfi_check_clear_intr_xscale;
398                 sc->mfi_issue_cmd = mfi_issue_cmd_xscale;
399         } else {
400                 sc->mfi_enable_intr =  mfi_enable_intr_ppc;
401                 sc->mfi_read_fw_status = mfi_read_fw_status_ppc;
402                 sc->mfi_check_clear_intr = mfi_check_clear_intr_ppc;
403                 sc->mfi_issue_cmd = mfi_issue_cmd_ppc;
404         }
405
406
407         /* Before we get too far, see if the firmware is working */
408         if ((error = mfi_transition_firmware(sc)) != 0) {
409                 device_printf(sc->mfi_dev, "Firmware not in READY state, "
410                     "error %d\n", error);
411                 return (ENXIO);
412         }
413
414         /*
415          * Get information needed for sizing the contiguous memory for the
416          * frame pool.  Size down the sgl parameter since we know that
417          * we will never need more than what's required for MAXPHYS.
418          * It would be nice if these constants were available at runtime
419          * instead of compile time.
420          */
421         status = sc->mfi_read_fw_status(sc);
422         sc->mfi_max_fw_cmds = status & MFI_FWSTATE_MAXCMD_MASK;
423         max_fw_sge = (status & MFI_FWSTATE_MAXSGL_MASK) >> 16;
424         sc->mfi_max_sge = min(max_fw_sge, ((MFI_MAXPHYS / PAGE_SIZE) + 1));
425
426         /*
427          * Create the dma tag for data buffers.  Used both for block I/O
428          * and for various internal data queries.
429          */
430         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
431                                 1, 0,                   /* algnmnt, boundary */
432                                 BUS_SPACE_MAXADDR,      /* lowaddr */
433                                 BUS_SPACE_MAXADDR,      /* highaddr */
434                                 NULL, NULL,             /* filter, filterarg */
435                                 BUS_SPACE_MAXSIZE_32BIT,/* maxsize */
436                                 sc->mfi_max_sge,        /* nsegments */
437                                 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
438                                 BUS_DMA_ALLOCNOW,       /* flags */
439                                 &sc->mfi_buffer_dmat)) {
440                 device_printf(sc->mfi_dev, "Cannot allocate buffer DMA tag\n");
441                 return (ENOMEM);
442         }
443
444         /*
445          * Allocate DMA memory for the comms queues.  Keep it under 4GB for
446          * efficiency.  The mfi_hwcomms struct includes space for 1 reply queue
447          * entry, so the calculated size here will be will be 1 more than
448          * mfi_max_fw_cmds.  This is apparently a requirement of the hardware.
449          */
450         commsz = (sizeof(uint32_t) * sc->mfi_max_fw_cmds) +
451             sizeof(struct mfi_hwcomms);
452         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
453                                 1, 0,                   /* algnmnt, boundary */
454                                 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
455                                 BUS_SPACE_MAXADDR,      /* highaddr */
456                                 NULL, NULL,             /* filter, filterarg */
457                                 commsz,                 /* maxsize */
458                                 1,                      /* msegments */
459                                 commsz,                 /* maxsegsize */
460                                 0,                      /* flags */
461                                 &sc->mfi_comms_dmat)) {
462                 device_printf(sc->mfi_dev, "Cannot allocate comms DMA tag\n");
463                 return (ENOMEM);
464         }
465         if (bus_dmamem_alloc(sc->mfi_comms_dmat, (void **)&sc->mfi_comms,
466             BUS_DMA_NOWAIT, &sc->mfi_comms_dmamap)) {
467                 device_printf(sc->mfi_dev, "Cannot allocate comms memory\n");
468                 return (ENOMEM);
469         }
470         bzero(sc->mfi_comms, commsz);
471 #if defined(__x86_64__)
472         bus_dmamap_load(sc->mfi_comms_dmat, sc->mfi_comms_dmamap,
473             sc->mfi_comms, commsz, mfi_addr64_cb, &sc->mfi_comms_busaddr, 0);
474 #else
475         bus_dmamap_load(sc->mfi_comms_dmat, sc->mfi_comms_dmamap,
476             sc->mfi_comms, commsz, mfi_addr32_cb, &sc->mfi_comms_busaddr, 0);
477 #endif
478
479         /*
480          * Allocate DMA memory for the command frames.  Keep them in the
481          * lower 4GB for efficiency.  Calculate the size of the commands at
482          * the same time; each command is one 64 byte frame plus a set of
483          * additional frames for holding sg lists or other data.
484          * The assumption here is that the SG list will start at the second
485          * frame and not use the unused bytes in the first frame.  While this
486          * isn't technically correct, it simplifies the calculation and allows
487          * for command frames that might be larger than an mfi_io_frame.
488          */
489         if (sizeof(bus_addr_t) == 8) {
490                 sc->mfi_sge_size = sizeof(struct mfi_sg64);
491                 sc->mfi_flags |= MFI_FLAGS_SG64;
492         } else {
493                 sc->mfi_sge_size = sizeof(struct mfi_sg32);
494         }
495         if (sc->mfi_flags & MFI_FLAGS_SKINNY)
496                 sc->mfi_sge_size = sizeof(struct mfi_sg_skinny);
497         frames = (sc->mfi_sge_size * sc->mfi_max_sge - 1) / MFI_FRAME_SIZE + 2;
498         sc->mfi_cmd_size = frames * MFI_FRAME_SIZE;
499         framessz = sc->mfi_cmd_size * sc->mfi_max_fw_cmds;
500         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
501                                 64, 0,                  /* algnmnt, boundary */
502                                 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
503                                 BUS_SPACE_MAXADDR,      /* highaddr */
504                                 NULL, NULL,             /* filter, filterarg */
505                                 framessz,               /* maxsize */
506                                 1,                      /* nsegments */
507                                 framessz,               /* maxsegsize */
508                                 0,                      /* flags */
509                                 &sc->mfi_frames_dmat)) {
510                 device_printf(sc->mfi_dev, "Cannot allocate frame DMA tag\n");
511                 return (ENOMEM);
512         }
513         if (bus_dmamem_alloc(sc->mfi_frames_dmat, (void **)&sc->mfi_frames,
514             BUS_DMA_NOWAIT, &sc->mfi_frames_dmamap)) {
515                 device_printf(sc->mfi_dev, "Cannot allocate frames memory\n");
516                 return (ENOMEM);
517         }
518         bzero(sc->mfi_frames, framessz);
519 #if defined(__x86_64__)
520         bus_dmamap_load(sc->mfi_frames_dmat, sc->mfi_frames_dmamap,
521             sc->mfi_frames, framessz, mfi_addr64_cb, &sc->mfi_frames_busaddr,0);
522 #else
523         bus_dmamap_load(sc->mfi_frames_dmat, sc->mfi_frames_dmamap,
524             sc->mfi_frames, framessz, mfi_addr32_cb, &sc->mfi_frames_busaddr,0);
525 #endif
526
527         /*
528          * Allocate DMA memory for the frame sense data.  Keep them in the
529          * lower 4GB for efficiency
530          */
531         sensesz = sc->mfi_max_fw_cmds * MFI_SENSE_LEN;
532         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
533                                 4, 0,                   /* algnmnt, boundary */
534                                 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
535                                 BUS_SPACE_MAXADDR,      /* highaddr */
536                                 NULL, NULL,             /* filter, filterarg */
537                                 sensesz,                /* maxsize */
538                                 1,                      /* nsegments */
539                                 sensesz,                /* maxsegsize */
540                                 0,                      /* flags */
541                                 &sc->mfi_sense_dmat)) {
542                 device_printf(sc->mfi_dev, "Cannot allocate sense DMA tag\n");
543                 return (ENOMEM);
544         }
545         if (bus_dmamem_alloc(sc->mfi_sense_dmat, (void **)&sc->mfi_sense,
546             BUS_DMA_NOWAIT, &sc->mfi_sense_dmamap)) {
547                 device_printf(sc->mfi_dev, "Cannot allocate sense memory\n");
548                 return (ENOMEM);
549         }
550 #if defined(__x86_64__)
551         bus_dmamap_load(sc->mfi_sense_dmat, sc->mfi_sense_dmamap,
552             sc->mfi_sense, sensesz, mfi_addr64_cb, &sc->mfi_sense_busaddr, 0);
553 #else
554         bus_dmamap_load(sc->mfi_sense_dmat, sc->mfi_sense_dmamap,
555             sc->mfi_sense, sensesz, mfi_addr32_cb, &sc->mfi_sense_busaddr, 0);
556 #endif
557
558         if ((error = mfi_alloc_commands(sc)) != 0)
559                 return (error);
560
561         if ((error = mfi_comms_init(sc)) != 0)
562                 return (error);
563
564         if ((error = mfi_get_controller_info(sc)) != 0)
565                 return (error);
566
567         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
568         if ((error = mfi_aen_setup(sc, 0), 0) != 0) {
569                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
570                 return (error);
571         }
572         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
573
574         /*
575          * Set up the interrupt handler.  XXX This should happen in
576          * mfi_pci.c
577          */
578         sc->mfi_irq_rid = 0;
579         sc->mfi_irq_type = pci_alloc_1intr(sc->mfi_dev, mfi_msi_enable,
580             &sc->mfi_irq_rid, &irq_flags);
581         if ((sc->mfi_irq = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_IRQ,
582             &sc->mfi_irq_rid, irq_flags)) == NULL) {
583                 device_printf(sc->mfi_dev, "Cannot allocate interrupt\n");
584                 return (EINVAL);
585         }
586         if (bus_setup_intr(sc->mfi_dev, sc->mfi_irq, INTR_MPSAFE,
587             mfi_intr, sc, &sc->mfi_intr, NULL)) {
588                 device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
589                 return (EINVAL);
590         }
591
592         /* Register a config hook to probe the bus for arrays */
593         sc->mfi_ich.ich_func = mfi_startup;
594         sc->mfi_ich.ich_arg = sc;
595         if (config_intrhook_establish(&sc->mfi_ich) != 0) {
596                 device_printf(sc->mfi_dev, "Cannot establish configuration "
597                     "hook\n");
598                 return (EINVAL);
599         }
600
601         /*
602          * Register a shutdown handler.
603          */
604         if ((sc->mfi_eh = EVENTHANDLER_REGISTER(shutdown_final, mfi_shutdown,
605             sc, SHUTDOWN_PRI_DEFAULT)) == NULL) {
606                 device_printf(sc->mfi_dev, "Warning: shutdown event "
607                     "registration failed\n");
608         }
609
610         /*
611          * Create the control device for doing management
612          */
613         unit = device_get_unit(sc->mfi_dev);
614         sc->mfi_cdev = make_dev(&mfi_ops, unit, UID_ROOT, GID_OPERATOR,
615             0640, "mfi%d", unit);
616         if (unit == 0)
617                 make_dev_alias(sc->mfi_cdev, "megaraid_sas_ioctl_node");
618         if (sc->mfi_cdev != NULL)
619                 sc->mfi_cdev->si_drv1 = sc;
620         sysctl_ctx_init(&sc->mfi_sysctl_ctx);
621         sc->mfi_sysctl_tree = SYSCTL_ADD_NODE(&sc->mfi_sysctl_ctx,
622             SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
623             device_get_nameunit(sc->mfi_dev), CTLFLAG_RD, 0, "");
624         if (sc->mfi_sysctl_tree == NULL) {
625                 device_printf(sc->mfi_dev, "can't add sysctl node\n");
626                 return (EINVAL);
627         }
628         SYSCTL_ADD_INT(&sc->mfi_sysctl_ctx,
629             SYSCTL_CHILDREN(sc->mfi_sysctl_tree),
630             OID_AUTO, "delete_busy_volumes", CTLFLAG_RW,
631             &sc->mfi_delete_busy_volumes, 0, "Allow removal of busy volumes");
632         SYSCTL_ADD_INT(&sc->mfi_sysctl_ctx,
633             SYSCTL_CHILDREN(sc->mfi_sysctl_tree),
634             OID_AUTO, "keep_deleted_volumes", CTLFLAG_RW,
635             &sc->mfi_keep_deleted_volumes, 0,
636             "Don't detach the mfid device for a busy volume that is deleted");
637
638         device_add_child(sc->mfi_dev, "mfip", -1);
639         bus_generic_attach(sc->mfi_dev);
640
641         /* Start the timeout watchdog */
642         callout_init_mp(&sc->mfi_watchdog_callout);
643         callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,
644             mfi_timeout, sc);
645
646         return (0);
647 }
648
649 static int
650 mfi_alloc_commands(struct mfi_softc *sc)
651 {
652         struct mfi_command *cm;
653         int i, ncmds;
654
655         /*
656          * XXX Should we allocate all the commands up front, or allocate on
657          * demand later like 'aac' does?
658          */
659         ncmds = MIN(mfi_max_cmds, sc->mfi_max_fw_cmds);
660         if (bootverbose)
661                 device_printf(sc->mfi_dev, "Max fw cmds= %d, sizing driver "
662                    "pool to %d\n", sc->mfi_max_fw_cmds, ncmds);
663
664         sc->mfi_commands = kmalloc(sizeof(struct mfi_command) * ncmds, M_MFIBUF,
665             M_WAITOK | M_ZERO);
666
667         for (i = 0; i < ncmds; i++) {
668                 cm = &sc->mfi_commands[i];
669                 cm->cm_frame = (union mfi_frame *)((uintptr_t)sc->mfi_frames +
670                     sc->mfi_cmd_size * i);
671                 cm->cm_frame_busaddr = sc->mfi_frames_busaddr +
672                     sc->mfi_cmd_size * i;
673                 cm->cm_frame->header.context = i;
674                 cm->cm_sense = &sc->mfi_sense[i];
675                 cm->cm_sense_busaddr= sc->mfi_sense_busaddr + MFI_SENSE_LEN * i;
676                 cm->cm_sc = sc;
677                 cm->cm_index = i;
678                 if (bus_dmamap_create(sc->mfi_buffer_dmat, 0,
679                     &cm->cm_dmamap) == 0)
680                         mfi_release_command(cm);
681                 else
682                         break;
683                 sc->mfi_total_cmds++;
684         }
685
686         return (0);
687 }
688
689 void
690 mfi_release_command(struct mfi_command *cm)
691 {
692         struct mfi_frame_header *hdr;
693         uint32_t *hdr_data;
694
695         /*
696          * Zero out the important fields of the frame, but make sure the
697          * context field is preserved.  For efficiency, handle the fields
698          * as 32 bit words.  Clear out the first S/G entry too for safety.
699          */
700         hdr = &cm->cm_frame->header;
701         if (cm->cm_data != NULL && hdr->sg_count) {
702                 cm->cm_sg->sg32[0].len = 0;
703                 cm->cm_sg->sg32[0].addr = 0;
704         }
705
706         hdr_data = (uint32_t *)cm->cm_frame;
707         hdr_data[0] = 0;        /* cmd, sense_len, cmd_status, scsi_status */
708         hdr_data[1] = 0;        /* target_id, lun_id, cdb_len, sg_count */
709         hdr_data[4] = 0;        /* flags, timeout */
710         hdr_data[5] = 0;        /* data_len */
711
712         cm->cm_extra_frames = 0;
713         cm->cm_flags = 0;
714         cm->cm_complete = NULL;
715         cm->cm_private = NULL;
716         cm->cm_data = NULL;
717         cm->cm_sg = 0;
718         cm->cm_total_frame_size = 0;
719
720         mfi_enqueue_free(cm);
721 }
722
723 static int
724 mfi_dcmd_command(struct mfi_softc *sc, struct mfi_command **cmp, uint32_t opcode,
725     void **bufp, size_t bufsize)
726 {
727         struct mfi_command *cm;
728         struct mfi_dcmd_frame *dcmd;
729         void *buf = NULL;
730         uint32_t context = 0;
731
732         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
733
734         cm = mfi_dequeue_free(sc);
735         if (cm == NULL)
736                 return (EBUSY);
737
738         /* Zero out the MFI frame */
739         context = cm->cm_frame->header.context;
740         bzero(cm->cm_frame, sizeof(union mfi_frame));
741         cm->cm_frame->header.context = context;
742
743         if ((bufsize > 0) && (bufp != NULL)) {
744                 if (*bufp == NULL) {
745                         buf = kmalloc(bufsize, M_MFIBUF, M_NOWAIT|M_ZERO);
746                         if (buf == NULL) {
747                                 mfi_release_command(cm);
748                                 return (ENOMEM);
749                         }
750                         *bufp = buf;
751                 } else {
752                         buf = *bufp;
753                 }
754         }
755
756         dcmd =  &cm->cm_frame->dcmd;
757         bzero(dcmd->mbox, MFI_MBOX_SIZE);
758         dcmd->header.cmd = MFI_CMD_DCMD;
759         dcmd->header.timeout = 0;
760         dcmd->header.flags = 0;
761         dcmd->header.data_len = bufsize;
762         dcmd->header.scsi_status = 0;
763         dcmd->opcode = opcode;
764         cm->cm_sg = &dcmd->sgl;
765         cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
766         cm->cm_flags = 0;
767         cm->cm_data = buf;
768         cm->cm_private = buf;
769         cm->cm_len = bufsize;
770
771         *cmp = cm;
772         if ((bufp != NULL) && (*bufp == NULL) && (buf != NULL))
773                 *bufp = buf;
774         return (0);
775 }
776
777 static int
778 mfi_comms_init(struct mfi_softc *sc)
779 {
780         struct mfi_command *cm;
781         struct mfi_init_frame *init;
782         struct mfi_init_qinfo *qinfo;
783         int error;
784         uint32_t context = 0;
785
786         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
787         if ((cm = mfi_dequeue_free(sc)) == NULL)
788                 return (EBUSY);
789
790         /* Zero out the MFI frame */
791         context = cm->cm_frame->header.context;
792         bzero(cm->cm_frame, sizeof(union mfi_frame));
793         cm->cm_frame->header.context = context;
794
795         /*
796          * Abuse the SG list area of the frame to hold the init_qinfo
797          * object;
798          */
799         init = &cm->cm_frame->init;
800         qinfo = (struct mfi_init_qinfo *)((uintptr_t)init + MFI_FRAME_SIZE);
801
802         bzero(qinfo, sizeof(struct mfi_init_qinfo));
803         qinfo->rq_entries = sc->mfi_max_fw_cmds + 1;
804         qinfo->rq_addr_lo = sc->mfi_comms_busaddr +
805             offsetof(struct mfi_hwcomms, hw_reply_q);
806         qinfo->pi_addr_lo = sc->mfi_comms_busaddr +
807             offsetof(struct mfi_hwcomms, hw_pi);
808         qinfo->ci_addr_lo = sc->mfi_comms_busaddr +
809             offsetof(struct mfi_hwcomms, hw_ci);
810
811         init->header.cmd = MFI_CMD_INIT;
812         init->header.data_len = sizeof(struct mfi_init_qinfo);
813         init->qinfo_new_addr_lo = cm->cm_frame_busaddr + MFI_FRAME_SIZE;
814         cm->cm_data = NULL;
815         cm->cm_flags = MFI_CMD_POLLED;
816
817         if ((error = mfi_mapcmd(sc, cm)) != 0) {
818                 device_printf(sc->mfi_dev, "failed to send init command\n");
819                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
820                 return (error);
821         }
822         mfi_release_command(cm);
823         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
824
825         return (0);
826 }
827
828 static int
829 mfi_get_controller_info(struct mfi_softc *sc)
830 {
831         struct mfi_command *cm = NULL;
832         struct mfi_ctrl_info *ci = NULL;
833         uint32_t max_sectors_1, max_sectors_2;
834         int error;
835
836         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
837         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_GETINFO,
838             (void **)&ci, sizeof(*ci));
839         if (error)
840                 goto out;
841         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
842
843         if ((error = mfi_mapcmd(sc, cm)) != 0) {
844                 device_printf(sc->mfi_dev, "Failed to get controller info\n");
845                 sc->mfi_max_io = (sc->mfi_max_sge - 1) * PAGE_SIZE /
846                     MFI_SECTOR_LEN;
847                 error = 0;
848                 goto out;
849         }
850
851         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
852             BUS_DMASYNC_POSTREAD);
853         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
854
855         max_sectors_1 = (1 << ci->stripe_sz_ops.min) * ci->max_strips_per_io;
856         max_sectors_2 = ci->max_request_size;
857         sc->mfi_max_io = min(max_sectors_1, max_sectors_2);
858
859 out:
860         if (ci)
861                 kfree(ci, M_MFIBUF);
862         if (cm)
863                 mfi_release_command(cm);
864         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
865         return (error);
866 }
867
868 static int
869 mfi_get_log_state(struct mfi_softc *sc, struct mfi_evt_log_state **log_state)
870 {
871         struct mfi_command *cm = NULL;
872         int error;
873
874         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_GETINFO,
875             (void **)log_state, sizeof(**log_state));
876         if (error)
877                 goto out;
878         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
879
880         if ((error = mfi_mapcmd(sc, cm)) != 0) {
881                 device_printf(sc->mfi_dev, "Failed to get log state\n");
882                 goto out;
883         }
884
885         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
886             BUS_DMASYNC_POSTREAD);
887         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
888
889 out:
890         if (cm)
891                 mfi_release_command(cm);
892
893         return (error);
894 }
895
896 static int
897 mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start)
898 {
899         struct mfi_evt_log_state *log_state = NULL;
900         union mfi_evt class_locale;
901         int error = 0;
902         uint32_t seq;
903
904         class_locale.members.reserved = 0;
905         class_locale.members.locale = mfi_event_locale;
906         class_locale.members.evt_class  = mfi_event_class;
907
908         if (seq_start == 0) {
909                 error = mfi_get_log_state(sc, &log_state);
910                 if (error) {
911                         if (log_state)
912                                 kfree(log_state, M_MFIBUF);
913                         return (error);
914                 }
915
916                 /*
917                  * Walk through any events that fired since the last
918                  * shutdown.
919                  */
920                 mfi_parse_entries(sc, log_state->shutdown_seq_num,
921                     log_state->newest_seq_num);
922                 seq = log_state->newest_seq_num;
923         } else
924                 seq = seq_start;
925         mfi_aen_register(sc, seq, class_locale.word);
926         if (log_state != NULL)
927                 kfree(log_state, M_MFIBUF);
928
929         return 0;
930 }
931
932 static int
933 mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm)
934 {
935
936         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
937         cm->cm_complete = NULL;
938
939
940         /*
941          * MegaCli can issue a DCMD of 0.  In this case do nothing
942          * and return 0 to it as status
943          */
944         if (cm->cm_frame->dcmd.opcode == 0) {
945                 cm->cm_frame->header.cmd_status = MFI_STAT_OK;
946                 cm->cm_error = 0;
947                 return (cm->cm_error);
948         }
949         mfi_enqueue_ready(cm);
950         mfi_startio(sc);
951         if ((cm->cm_flags & MFI_CMD_COMPLETED) == 0)
952                 lksleep(cm, &sc->mfi_io_lock, 0, "mfiwait", 0);
953         return (cm->cm_error);
954 }
955
956 void
957 mfi_free(struct mfi_softc *sc)
958 {
959         struct mfi_command *cm;
960         int i;
961
962         callout_stop(&sc->mfi_watchdog_callout); /* XXX callout_drain() */
963
964         if (sc->mfi_cdev != NULL)
965                 destroy_dev(sc->mfi_cdev);
966         dev_ops_remove_minor(&mfi_ops, device_get_unit(sc->mfi_dev));
967
968         if (sc->mfi_total_cmds != 0) {
969                 for (i = 0; i < sc->mfi_total_cmds; i++) {
970                         cm = &sc->mfi_commands[i];
971                         bus_dmamap_destroy(sc->mfi_buffer_dmat, cm->cm_dmamap);
972                 }
973                 kfree(sc->mfi_commands, M_MFIBUF);
974         }
975
976         if (sc->mfi_intr)
977                 bus_teardown_intr(sc->mfi_dev, sc->mfi_irq, sc->mfi_intr);
978         if (sc->mfi_irq != NULL)
979                 bus_release_resource(sc->mfi_dev, SYS_RES_IRQ, sc->mfi_irq_rid,
980                     sc->mfi_irq);
981         if (sc->mfi_irq_type == PCI_INTR_TYPE_MSI)
982                 pci_release_msi(sc->mfi_dev);
983         if (sc->mfi_sense_busaddr != 0)
984                 bus_dmamap_unload(sc->mfi_sense_dmat, sc->mfi_sense_dmamap);
985         if (sc->mfi_sense != NULL)
986                 bus_dmamem_free(sc->mfi_sense_dmat, sc->mfi_sense,
987                     sc->mfi_sense_dmamap);
988         if (sc->mfi_sense_dmat != NULL)
989                 bus_dma_tag_destroy(sc->mfi_sense_dmat);
990
991         if (sc->mfi_frames_busaddr != 0)
992                 bus_dmamap_unload(sc->mfi_frames_dmat, sc->mfi_frames_dmamap);
993         if (sc->mfi_frames != NULL)
994                 bus_dmamem_free(sc->mfi_frames_dmat, sc->mfi_frames,
995                     sc->mfi_frames_dmamap);
996         if (sc->mfi_frames_dmat != NULL)
997                 bus_dma_tag_destroy(sc->mfi_frames_dmat);
998
999         if (sc->mfi_comms_busaddr != 0)
1000                 bus_dmamap_unload(sc->mfi_comms_dmat, sc->mfi_comms_dmamap);
1001         if (sc->mfi_comms != NULL)
1002                 bus_dmamem_free(sc->mfi_comms_dmat, sc->mfi_comms,
1003                     sc->mfi_comms_dmamap);
1004         if (sc->mfi_comms_dmat != NULL)
1005                 bus_dma_tag_destroy(sc->mfi_comms_dmat);
1006
1007         if (sc->mfi_buffer_dmat != NULL)
1008                 bus_dma_tag_destroy(sc->mfi_buffer_dmat);
1009         if (sc->mfi_parent_dmat != NULL)
1010                 bus_dma_tag_destroy(sc->mfi_parent_dmat);
1011
1012         if (sc->mfi_sysctl_tree != NULL)
1013                 sysctl_ctx_free(&sc->mfi_sysctl_ctx);
1014
1015 #if 0 /* XXX swildner: not sure if we need something like mtx_initialized() */
1016         if (mtx_initialized(&sc->mfi_io_lock))
1017 #endif
1018         {
1019         lockuninit(&sc->mfi_io_lock);
1020         lockuninit(&sc->mfi_config_lock);
1021         }
1022
1023         return;
1024 }
1025
1026 static void
1027 mfi_startup(void *arg)
1028 {
1029         struct mfi_softc *sc;
1030
1031         sc = (struct mfi_softc *)arg;
1032
1033         config_intrhook_disestablish(&sc->mfi_ich);
1034
1035         sc->mfi_enable_intr(sc);
1036         lockmgr(&sc->mfi_config_lock, LK_EXCLUSIVE);
1037         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1038         mfi_ldprobe(sc);
1039         if (sc->mfi_flags & MFI_FLAGS_SKINNY)
1040                 mfi_syspdprobe(sc);
1041         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1042         lockmgr(&sc->mfi_config_lock, LK_RELEASE);
1043 }
1044
1045 static void
1046 mfi_intr(void *arg)
1047 {
1048         struct mfi_softc *sc;
1049         struct mfi_command *cm;
1050         uint32_t pi, ci, context;
1051
1052         sc = (struct mfi_softc *)arg;
1053
1054         if (sc->mfi_check_clear_intr(sc))
1055                 return;
1056
1057         /*
1058          * Do a dummy read to flush the interrupt ACK that we just performed,
1059          * ensuring that everything is really, truly consistent.
1060          */
1061         (void)sc->mfi_read_fw_status(sc);
1062
1063         pi = sc->mfi_comms->hw_pi;
1064         ci = sc->mfi_comms->hw_ci;
1065         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1066         while (ci != pi) {
1067                 context = sc->mfi_comms->hw_reply_q[ci];
1068                 if (context < sc->mfi_max_fw_cmds) {
1069                         cm = &sc->mfi_commands[context];
1070                         mfi_remove_busy(cm);
1071                         cm->cm_error = 0;
1072                         mfi_complete(sc, cm);
1073                 }
1074                 if (++ci == (sc->mfi_max_fw_cmds + 1)) {
1075                         ci = 0;
1076                 }
1077         }
1078
1079         sc->mfi_comms->hw_ci = ci;
1080
1081         /* Give defered I/O a chance to run */
1082         if (sc->mfi_flags & MFI_FLAGS_QFRZN)
1083                 sc->mfi_flags &= ~MFI_FLAGS_QFRZN;
1084         mfi_startio(sc);
1085         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1086
1087         return;
1088 }
1089
1090 int
1091 mfi_shutdown(struct mfi_softc *sc)
1092 {
1093         struct mfi_dcmd_frame *dcmd;
1094         struct mfi_command *cm;
1095         int error;
1096
1097         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1098         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_SHUTDOWN, NULL, 0);
1099         if (error) {
1100                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1101                 return (error);
1102         }
1103
1104         if (sc->mfi_aen_cm != NULL)
1105                 mfi_abort(sc, sc->mfi_aen_cm);
1106
1107         dcmd = &cm->cm_frame->dcmd;
1108         dcmd->header.flags = MFI_FRAME_DIR_NONE;
1109         cm->cm_flags = MFI_CMD_POLLED;
1110         cm->cm_data = NULL;
1111
1112         if ((error = mfi_mapcmd(sc, cm)) != 0) {
1113                 device_printf(sc->mfi_dev, "Failed to shutdown controller\n");
1114         }
1115
1116         mfi_release_command(cm);
1117         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1118         return (error);
1119 }
1120 static void
1121 mfi_syspdprobe(struct mfi_softc *sc)
1122 {
1123         struct mfi_frame_header *hdr;
1124         struct mfi_command *cm = NULL;
1125         struct mfi_pd_list *pdlist = NULL;
1126         struct mfi_system_pd *syspd;
1127         int error, i;
1128
1129         KKASSERT(lockstatus(&sc->mfi_config_lock, curthread) != 0);
1130         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1131         /* Add SYSTEM PD's */
1132         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_PD_LIST_QUERY,
1133             (void **)&pdlist, sizeof(*pdlist));
1134         if (error) {
1135                 device_printf(sc->mfi_dev,"Error while forming syspd list\n");
1136                 goto out;
1137         }
1138
1139         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
1140         cm->cm_frame->dcmd.mbox[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
1141         cm->cm_frame->dcmd.mbox[1] = 0;
1142         if (mfi_mapcmd(sc, cm) != 0) {
1143                 device_printf(sc->mfi_dev, "Failed to get syspd device list\n");
1144                 goto out;
1145         }
1146         bus_dmamap_sync(sc->mfi_buffer_dmat,cm->cm_dmamap,
1147             BUS_DMASYNC_POSTREAD);
1148         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
1149         hdr = &cm->cm_frame->header;
1150         if (hdr->cmd_status != MFI_STAT_OK) {
1151                 device_printf(sc->mfi_dev, "MFI_DCMD_PD_LIST_QUERY failed %x\n",
1152                     hdr->cmd_status);
1153                 goto out;
1154         }
1155         for (i = 0; i < pdlist->count; i++) {
1156                 if (pdlist->addr[i].device_id == pdlist->addr[i].encl_device_id)
1157                         goto skip_sys_pd_add;
1158                 /* Get each PD and add it to the system */
1159                 if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
1160                         TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh,pd_link) {
1161                                 if (syspd->pd_id == pdlist->addr[i].device_id)
1162                                         goto skip_sys_pd_add;
1163                         }
1164                 }
1165                 mfi_add_sys_pd(sc,pdlist->addr[i].device_id);
1166 skip_sys_pd_add:
1167                 ;
1168         }
1169         /* Delete SYSPD's whose state has been changed */
1170         if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
1171                 TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh,pd_link) {
1172                         for (i=0;i<pdlist->count;i++) {
1173                                 if (syspd->pd_id == pdlist->addr[i].device_id)
1174                                         goto skip_sys_pd_delete;
1175                         }
1176                         get_mplock();
1177                         device_delete_child(sc->mfi_dev,syspd->pd_dev);
1178                         rel_mplock();
1179 skip_sys_pd_delete:
1180                         ;
1181                 }
1182         }
1183 out:
1184         if (pdlist)
1185                 kfree(pdlist, M_MFIBUF);
1186         if (cm)
1187                 mfi_release_command(cm);
1188 }
1189
1190 static void
1191 mfi_ldprobe(struct mfi_softc *sc)
1192 {
1193         struct mfi_frame_header *hdr;
1194         struct mfi_command *cm = NULL;
1195         struct mfi_ld_list *list = NULL;
1196         struct mfi_disk *ld;
1197         int error, i;
1198
1199         KKASSERT(lockstatus(&sc->mfi_config_lock, curthread) != 0);
1200         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1201
1202         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_LIST,
1203             (void **)&list, sizeof(*list));
1204         if (error)
1205                 goto out;
1206
1207         cm->cm_flags = MFI_CMD_DATAIN;
1208         if (mfi_wait_command(sc, cm) != 0) {
1209                 device_printf(sc->mfi_dev, "Failed to get device listing\n");
1210                 goto out;
1211         }
1212
1213         hdr = &cm->cm_frame->header;
1214         if (hdr->cmd_status != MFI_STAT_OK) {
1215                 device_printf(sc->mfi_dev, "MFI_DCMD_LD_GET_LIST failed %x\n",
1216                     hdr->cmd_status);
1217                 goto out;
1218         }
1219
1220         for (i = 0; i < list->ld_count; i++) {
1221                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
1222                         if (ld->ld_id == list->ld_list[i].ld.v.target_id)
1223                                 goto skip_add;
1224                 }
1225                 mfi_add_ld(sc, list->ld_list[i].ld.v.target_id);
1226         skip_add:;
1227         }
1228 out:
1229         if (list)
1230                 kfree(list, M_MFIBUF);
1231         if (cm)
1232                 mfi_release_command(cm);
1233
1234         return;
1235 }
1236
1237 /*
1238  * The timestamp is the number of seconds since 00:00 Jan 1, 2000.  If
1239  * the bits in 24-31 are all set, then it is the number of seconds since
1240  * boot.
1241  */
1242 static const char *
1243 format_timestamp(uint32_t timestamp)
1244 {
1245         static char buffer[32];
1246
1247         if ((timestamp & 0xff000000) == 0xff000000)
1248                 ksnprintf(buffer, sizeof(buffer), "boot + %us", timestamp &
1249                     0x00ffffff);
1250         else
1251                 ksnprintf(buffer, sizeof(buffer), "%us", timestamp);
1252         return (buffer);
1253 }
1254
1255 static const char *
1256 format_class(int8_t class)
1257 {
1258         static char buffer[6];
1259
1260         switch (class) {
1261         case MFI_EVT_CLASS_DEBUG:
1262                 return ("debug");
1263         case MFI_EVT_CLASS_PROGRESS:
1264                 return ("progress");
1265         case MFI_EVT_CLASS_INFO:
1266                 return ("info");
1267         case MFI_EVT_CLASS_WARNING:
1268                 return ("WARN");
1269         case MFI_EVT_CLASS_CRITICAL:
1270                 return ("CRIT");
1271         case MFI_EVT_CLASS_FATAL:
1272                 return ("FATAL");
1273         case MFI_EVT_CLASS_DEAD:
1274                 return ("DEAD");
1275         default:
1276                 ksnprintf(buffer, sizeof(buffer), "%d", class);
1277                 return (buffer);
1278         }
1279 }
1280
1281 static void
1282 mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail)
1283 {
1284
1285         device_printf(sc->mfi_dev, "%d (%s/0x%04x/%s) - %s\n", detail->seq,
1286             format_timestamp(detail->time), detail->evt_class.members.locale,
1287             format_class(detail->evt_class.members.evt_class), detail->description);
1288 }
1289
1290 static int
1291 mfi_aen_register(struct mfi_softc *sc, int seq, int locale)
1292 {
1293         struct mfi_command *cm;
1294         struct mfi_dcmd_frame *dcmd;
1295         union mfi_evt current_aen, prior_aen;
1296         struct mfi_evt_detail *ed = NULL;
1297         int error = 0;
1298
1299         current_aen.word = locale;
1300         if (sc->mfi_aen_cm != NULL) {
1301                 prior_aen.word =
1302                     ((uint32_t *)&sc->mfi_aen_cm->cm_frame->dcmd.mbox)[1];
1303                 if (prior_aen.members.evt_class <= current_aen.members.evt_class &&
1304                     !((prior_aen.members.locale & current_aen.members.locale)
1305                     ^current_aen.members.locale)) {
1306                         return (0);
1307                 } else {
1308                         prior_aen.members.locale |= current_aen.members.locale;
1309                         if (prior_aen.members.evt_class
1310                             < current_aen.members.evt_class)
1311                                 current_aen.members.evt_class =
1312                                     prior_aen.members.evt_class;
1313                         mfi_abort(sc, sc->mfi_aen_cm);
1314                 }
1315         }
1316
1317         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_WAIT,
1318             (void **)&ed, sizeof(*ed));
1319         if (error) {
1320                 goto out;
1321         }
1322
1323         dcmd = &cm->cm_frame->dcmd;
1324         ((uint32_t *)&dcmd->mbox)[0] = seq;
1325         ((uint32_t *)&dcmd->mbox)[1] = locale;
1326         cm->cm_flags = MFI_CMD_DATAIN;
1327         cm->cm_complete = mfi_aen_complete;
1328
1329         sc->mfi_aen_cm = cm;
1330
1331         mfi_enqueue_ready(cm);
1332         mfi_startio(sc);
1333
1334 out:
1335         return (error);
1336 }
1337
1338 static void
1339 mfi_aen_complete(struct mfi_command *cm)
1340 {
1341         struct mfi_frame_header *hdr;
1342         struct mfi_softc *sc;
1343         struct mfi_evt_detail *detail;
1344         struct mfi_aen *mfi_aen_entry, *tmp;
1345         int seq = 0, aborted = 0;
1346
1347         sc = cm->cm_sc;
1348         hdr = &cm->cm_frame->header;
1349
1350         if (sc->mfi_aen_cm == NULL)
1351                 return;
1352
1353         if (sc->mfi_aen_cm->cm_aen_abort ||
1354             hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
1355                 sc->mfi_aen_cm->cm_aen_abort = 0;
1356                 aborted = 1;
1357         } else {
1358                 sc->mfi_aen_triggered = 1;
1359                 if (sc->mfi_poll_waiting) {
1360                         sc->mfi_poll_waiting = 0;
1361                         KNOTE(&sc->mfi_kq.ki_note, 0);
1362                 }
1363                 detail = cm->cm_data;
1364                 /*
1365                  * XXX If this function is too expensive or is recursive, then
1366                  * events should be put onto a queue and processed later.
1367                  */
1368                 mfi_decode_evt(sc, detail);
1369                 seq = detail->seq + 1;
1370                 TAILQ_FOREACH_MUTABLE(mfi_aen_entry, &sc->mfi_aen_pids, aen_link, tmp) {
1371                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
1372                             aen_link);
1373                         lwkt_gettoken(&proc_token);
1374                         ksignal(mfi_aen_entry->p, SIGIO);
1375                         lwkt_reltoken(&proc_token);
1376                         kfree(mfi_aen_entry, M_MFIBUF);
1377                 }
1378         }
1379
1380         kfree(cm->cm_data, M_MFIBUF);
1381         sc->mfi_aen_cm = NULL;
1382         wakeup(&sc->mfi_aen_cm);
1383         mfi_release_command(cm);
1384
1385         /* set it up again so the driver can catch more events */
1386         if (!aborted) {
1387                 mfi_aen_setup(sc, seq);
1388         }
1389 }
1390
1391 #define MAX_EVENTS 15
1392
1393 static int
1394 mfi_parse_entries(struct mfi_softc *sc, int start_seq, int stop_seq)
1395 {
1396         struct mfi_command *cm;
1397         struct mfi_dcmd_frame *dcmd;
1398         struct mfi_evt_list *el;
1399         union mfi_evt class_locale;
1400         int error, i, seq, size;
1401         uint32_t context = 0;
1402
1403         class_locale.members.reserved = 0;
1404         class_locale.members.locale = mfi_event_locale;
1405         class_locale.members.evt_class  = mfi_event_class;
1406
1407         size = sizeof(struct mfi_evt_list) + sizeof(struct mfi_evt_detail)
1408                 * (MAX_EVENTS - 1);
1409         el = kmalloc(size, M_MFIBUF, M_NOWAIT | M_ZERO);
1410         if (el == NULL)
1411                 return (ENOMEM);
1412
1413         for (seq = start_seq;;) {
1414                 if ((cm = mfi_dequeue_free(sc)) == NULL) {
1415                         kfree(el, M_MFIBUF);
1416                         return (EBUSY);
1417                 }
1418
1419                 /* Zero out the MFI frame */
1420                 context = cm->cm_frame->header.context;
1421                 bzero(cm->cm_frame, sizeof(union mfi_frame));
1422                 cm->cm_frame->header.context = context;
1423
1424                 dcmd = &cm->cm_frame->dcmd;
1425                 bzero(dcmd->mbox, MFI_MBOX_SIZE);
1426                 dcmd->header.cmd = MFI_CMD_DCMD;
1427                 dcmd->header.timeout = 0;
1428                 dcmd->header.data_len = size;
1429                 dcmd->header.scsi_status = 0;
1430                 dcmd->opcode = MFI_DCMD_CTRL_EVENT_GET;
1431                 ((uint32_t *)&dcmd->mbox)[0] = seq;
1432                 ((uint32_t *)&dcmd->mbox)[1] = class_locale.word;
1433                 cm->cm_sg = &dcmd->sgl;
1434                 cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
1435                 cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
1436                 cm->cm_data = el;
1437                 cm->cm_len = size;
1438
1439                 if ((error = mfi_mapcmd(sc, cm)) != 0) {
1440                         device_printf(sc->mfi_dev,
1441                             "Failed to get controller entries\n");
1442                         mfi_release_command(cm);
1443                         break;
1444                 }
1445
1446                 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
1447                     BUS_DMASYNC_POSTREAD);
1448                 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
1449
1450                 if (dcmd->header.cmd_status == MFI_STAT_NOT_FOUND) {
1451                         mfi_release_command(cm);
1452                         break;
1453                 }
1454                 if (dcmd->header.cmd_status != MFI_STAT_OK) {
1455                         device_printf(sc->mfi_dev,
1456                             "Error %d fetching controller entries\n",
1457                             dcmd->header.cmd_status);
1458                         mfi_release_command(cm);
1459                         break;
1460                 }
1461                 mfi_release_command(cm);
1462
1463                 for (i = 0; i < el->count; i++) {
1464                         /*
1465                          * If this event is newer than 'stop_seq' then
1466                          * break out of the loop.  Note that the log
1467                          * is a circular buffer so we have to handle
1468                          * the case that our stop point is earlier in
1469                          * the buffer than our start point.
1470                          */
1471                         if (el->event[i].seq >= stop_seq) {
1472                                 if (start_seq <= stop_seq)
1473                                         break;
1474                                 else if (el->event[i].seq < start_seq)
1475                                         break;
1476                         }
1477                         mfi_decode_evt(sc, &el->event[i]);
1478                 }
1479                 seq = el->event[el->count - 1].seq + 1;
1480         }
1481
1482         kfree(el, M_MFIBUF);
1483         return (0);
1484 }
1485
1486 static int
1487 mfi_add_ld(struct mfi_softc *sc, int id)
1488 {
1489         struct mfi_command *cm;
1490         struct mfi_dcmd_frame *dcmd = NULL;
1491         struct mfi_ld_info *ld_info = NULL;
1492         int error;
1493
1494         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1495
1496         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_INFO,
1497             (void **)&ld_info, sizeof(*ld_info));
1498         if (error) {
1499                 device_printf(sc->mfi_dev,
1500                     "Failed to allocate for MFI_DCMD_LD_GET_INFO %d\n", error);
1501                 if (ld_info)
1502                         kfree(ld_info, M_MFIBUF);
1503                 return (error);
1504         }
1505         cm->cm_flags = MFI_CMD_DATAIN;
1506         dcmd = &cm->cm_frame->dcmd;
1507         dcmd->mbox[0] = id;
1508         if (mfi_wait_command(sc, cm) != 0) {
1509                 device_printf(sc->mfi_dev,
1510                     "Failed to get logical drive: %d\n", id);
1511                 kfree(ld_info, M_MFIBUF);
1512                 return (0);
1513         }
1514         if (ld_info->ld_config.params.isSSCD != 1) {
1515                 mfi_add_ld_complete(cm);
1516         } else {
1517                 mfi_release_command(cm);
1518                 if(ld_info)             /* SSCD drives ld_info free here */
1519                         kfree(ld_info, M_MFIBUF);
1520         }
1521         return (0);
1522 }
1523
1524 static void
1525 mfi_add_ld_complete(struct mfi_command *cm)
1526 {
1527         struct mfi_frame_header *hdr;
1528         struct mfi_ld_info *ld_info;
1529         struct mfi_softc *sc;
1530         device_t child;
1531
1532         sc = cm->cm_sc;
1533         hdr = &cm->cm_frame->header;
1534         ld_info = cm->cm_private;
1535
1536         if (hdr->cmd_status != MFI_STAT_OK) {
1537                 kfree(ld_info, M_MFIBUF);
1538                 mfi_release_command(cm);
1539                 return;
1540         }
1541         mfi_release_command(cm);
1542
1543         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1544         get_mplock();
1545         if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) {
1546                 device_printf(sc->mfi_dev, "Failed to add logical disk\n");
1547                 kfree(ld_info, M_MFIBUF);
1548                 rel_mplock();
1549                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1550                 return;
1551         }
1552
1553         device_set_ivars(child, ld_info);
1554         device_set_desc(child, "MFI Logical Disk");
1555         bus_generic_attach(sc->mfi_dev);
1556         rel_mplock();
1557         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1558 }
1559
1560 static int
1561 mfi_add_sys_pd(struct mfi_softc *sc,int id)
1562 {
1563         struct mfi_command *cm;
1564         struct mfi_dcmd_frame *dcmd = NULL;
1565         struct mfi_pd_info *pd_info = NULL;
1566         int error;
1567
1568         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1569
1570         error = mfi_dcmd_command(sc,&cm,MFI_DCMD_PD_GET_INFO,
1571             (void **)&pd_info, sizeof(*pd_info));
1572         if (error) {
1573                 device_printf(sc->mfi_dev,
1574                     "Failed to allocated for MFI_DCMD_PD_GET_INFO %d\n", error);
1575                 if (pd_info)
1576                         kfree(pd_info,M_MFIBUF);
1577                 return (error);
1578         }
1579         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
1580         dcmd = &cm->cm_frame->dcmd;
1581         dcmd->mbox[0] = id;
1582         dcmd->header.scsi_status = 0;
1583         dcmd->header.pad0 = 0;
1584         if (mfi_mapcmd(sc, cm) != 0) {
1585                 device_printf(sc->mfi_dev,
1586                     "Failed to get physical drive info %d\n", id);
1587                 kfree(pd_info,M_MFIBUF);
1588                 return (0);
1589         }
1590         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
1591             BUS_DMASYNC_POSTREAD);
1592         bus_dmamap_unload(sc->mfi_buffer_dmat,cm->cm_dmamap);
1593         mfi_add_sys_pd_complete(cm);
1594         return (0);
1595 }
1596
1597 static void
1598 mfi_add_sys_pd_complete(struct mfi_command *cm)
1599 {
1600         struct mfi_frame_header *hdr;
1601         struct mfi_pd_info *pd_info;
1602         struct mfi_softc *sc;
1603         device_t child;
1604
1605         sc = cm->cm_sc;
1606         hdr = &cm->cm_frame->header;
1607         pd_info = cm->cm_private;
1608
1609         if (hdr->cmd_status != MFI_STAT_OK) {
1610                 kfree(pd_info, M_MFIBUF);
1611                 mfi_release_command(cm);
1612                 return;
1613         }
1614         if (pd_info->fw_state != MFI_PD_STATE_SYSTEM) {
1615                 device_printf(sc->mfi_dev,"PD=%x is not SYSTEM PD\n",
1616                     pd_info->ref.v.device_id);
1617                 kfree(pd_info, M_MFIBUF);
1618                 mfi_release_command(cm);
1619                 return;
1620         }
1621         mfi_release_command(cm);
1622
1623         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1624         get_mplock();
1625         if ((child = device_add_child(sc->mfi_dev, "mfisyspd", -1)) == NULL) {
1626                 device_printf(sc->mfi_dev, "Failed to add system pd\n");
1627                 kfree(pd_info, M_MFIBUF);
1628                 rel_mplock();
1629                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1630                 return;
1631         }
1632
1633         device_set_ivars(child, pd_info);
1634         device_set_desc(child, "MFI System PD");
1635         bus_generic_attach(sc->mfi_dev);
1636         rel_mplock();
1637         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1638 }
1639
1640 static struct mfi_command *
1641 mfi_bio_command(struct mfi_softc *sc)
1642 {
1643         struct bio *bio;
1644         struct mfi_command *cm = NULL;
1645         struct mfi_disk *mfid;
1646
1647         /* reserving two commands to avoid starvation for IOCTL */
1648         if (sc->mfi_qstat[MFIQ_FREE].q_length < 2)
1649                 return (NULL);
1650         if ((bio = mfi_dequeue_bio(sc)) == NULL)
1651                 return (NULL);
1652         mfid = bio->bio_driver_info;
1653         if (mfid->ld_flags & MFI_DISK_FLAGS_SYSPD)
1654                 cm = mfi_build_syspdio(sc, bio);
1655         else
1656                 cm = mfi_build_ldio(sc, bio);
1657         if (!cm)
1658                 mfi_enqueue_bio(sc,bio);
1659         return cm;
1660 }
1661
1662 static struct mfi_command *
1663 mfi_build_syspdio(struct mfi_softc *sc, struct bio *bio)
1664 {
1665         struct mfi_command *cm;
1666         struct buf *bp;
1667         struct mfi_system_pd *disk;
1668         struct mfi_pass_frame *pass;
1669         int flags = 0,blkcount = 0;
1670         uint32_t context = 0;
1671
1672         if ((cm = mfi_dequeue_free(sc)) == NULL)
1673                 return (NULL);
1674
1675         /* Zero out the MFI frame */
1676         context = cm->cm_frame->header.context;
1677         bzero(cm->cm_frame, sizeof(union mfi_frame));
1678         cm->cm_frame->header.context = context;
1679         bp = bio->bio_buf;
1680         pass = &cm->cm_frame->pass;
1681         bzero(pass->cdb, 16);
1682         pass->header.cmd = MFI_CMD_PD_SCSI_IO;
1683         switch (bp->b_cmd & 0x03) {
1684         case BUF_CMD_READ:
1685                 pass->cdb[0] = READ_10;
1686                 flags = MFI_CMD_DATAIN;
1687                 break;
1688         case BUF_CMD_WRITE:
1689                 pass->cdb[0] = WRITE_10;
1690                 flags = MFI_CMD_DATAOUT;
1691                 break;
1692         default:
1693                 panic("Invalid bio command");
1694         }
1695
1696         /* Cheat with the sector length to avoid a non-constant division */
1697         blkcount = (bp->b_bcount + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
1698         disk = bio->bio_driver_info;
1699         /* Fill the LBA and Transfer length in CDB */
1700         pass->cdb[2] = ((bio->bio_offset / MFI_SECTOR_LEN) & 0xff000000) >> 24;
1701         pass->cdb[3] = ((bio->bio_offset / MFI_SECTOR_LEN) & 0x00ff0000) >> 16;
1702         pass->cdb[4] = ((bio->bio_offset / MFI_SECTOR_LEN) & 0x0000ff00) >> 8;
1703         pass->cdb[5] = (bio->bio_offset / MFI_SECTOR_LEN) & 0x000000ff;
1704         pass->cdb[7] = (blkcount & 0xff00) >> 8;
1705         pass->cdb[8] = (blkcount & 0x00ff);
1706         pass->header.target_id = disk->pd_id;
1707         pass->header.timeout = 0;
1708         pass->header.flags = 0;
1709         pass->header.scsi_status = 0;
1710         pass->header.sense_len = MFI_SENSE_LEN;
1711         pass->header.data_len = bp->b_bcount;
1712         pass->header.cdb_len = 10;
1713 #if defined(__x86_64__)
1714         pass->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
1715         pass->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000) >> 32;
1716 #else
1717         pass->sense_addr_lo = cm->cm_sense_busaddr;
1718         pass->sense_addr_hi = 0;
1719 #endif
1720         cm->cm_complete = mfi_bio_complete;
1721         cm->cm_private = bio;
1722         cm->cm_data = bp->b_data;
1723         cm->cm_len = bp->b_bcount;
1724         cm->cm_sg = &pass->sgl;
1725         cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE;
1726         cm->cm_flags = flags;
1727         return (cm);
1728 }
1729
1730 static struct mfi_command *
1731 mfi_build_ldio(struct mfi_softc *sc,struct bio *bio)
1732 {
1733         struct mfi_io_frame *io;
1734         struct buf *bp;
1735         struct mfi_disk *disk;
1736         struct mfi_command *cm;
1737         int flags, blkcount;
1738         uint32_t context = 0;
1739
1740         if ((cm = mfi_dequeue_free(sc)) == NULL)
1741             return (NULL);
1742
1743         /* Zero out the MFI frame */
1744         context = cm->cm_frame->header.context;
1745         bzero(cm->cm_frame,sizeof(union mfi_frame));
1746         cm->cm_frame->header.context = context;
1747         bp = bio->bio_buf;
1748         io = &cm->cm_frame->io;
1749         switch (bp->b_cmd & 0x03) {
1750         case BUF_CMD_READ:
1751                 io->header.cmd = MFI_CMD_LD_READ;
1752                 flags = MFI_CMD_DATAIN;
1753                 break;
1754         case BUF_CMD_WRITE:
1755                 io->header.cmd = MFI_CMD_LD_WRITE;
1756                 flags = MFI_CMD_DATAOUT;
1757                 break;
1758         default:
1759                 panic("Invalid bio command");
1760         }
1761
1762         /* Cheat with the sector length to avoid a non-constant division */
1763         blkcount = (bp->b_bcount + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
1764         disk = bio->bio_driver_info;
1765         io->header.target_id = disk->ld_id;
1766         io->header.timeout = 0;
1767         io->header.flags = 0;
1768         io->header.scsi_status = 0;
1769         io->header.sense_len = MFI_SENSE_LEN;
1770         io->header.data_len = blkcount;
1771 #if defined(__x86_64__)
1772         io->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
1773         io->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000) >> 32;
1774 #else
1775         io->sense_addr_lo = cm->cm_sense_busaddr;
1776         io->sense_addr_hi = 0;
1777 #endif
1778         io->lba_hi = ((bio->bio_offset / MFI_SECTOR_LEN) & 0xffffffff00000000) >> 32;
1779         io->lba_lo = (bio->bio_offset / MFI_SECTOR_LEN) & 0xffffffff;
1780         cm->cm_complete = mfi_bio_complete;
1781         cm->cm_private = bio;
1782         cm->cm_data = bp->b_data;
1783         cm->cm_len = bp->b_bcount;
1784         cm->cm_sg = &io->sgl;
1785         cm->cm_total_frame_size = MFI_IO_FRAME_SIZE;
1786         cm->cm_flags = flags;
1787         return (cm);
1788 }
1789
1790 static void
1791 mfi_bio_complete(struct mfi_command *cm)
1792 {
1793         struct bio *bio;
1794         struct buf *bp;
1795         struct mfi_frame_header *hdr;
1796         struct mfi_softc *sc;
1797
1798         bio = cm->cm_private;
1799         bp = bio->bio_buf;
1800         hdr = &cm->cm_frame->header;
1801         sc = cm->cm_sc;
1802
1803         if ((hdr->cmd_status != MFI_STAT_OK) || (hdr->scsi_status != 0)) {
1804                 bp->b_flags |= B_ERROR;
1805                 bp->b_error = EIO;
1806                 device_printf(sc->mfi_dev, "I/O error, status= %d "
1807                     "scsi_status= %d\n", hdr->cmd_status, hdr->scsi_status);
1808                 mfi_print_sense(cm->cm_sc, cm->cm_sense);
1809         } else if (cm->cm_error != 0) {
1810                 bp->b_flags |= B_ERROR;
1811         }
1812
1813         mfi_release_command(cm);
1814         mfi_disk_complete(bio);
1815 }
1816
1817 void
1818 mfi_startio(struct mfi_softc *sc)
1819 {
1820         struct mfi_command *cm;
1821         struct ccb_hdr *ccbh;
1822
1823         for (;;) {
1824                 /* Don't bother if we're short on resources */
1825                 if (sc->mfi_flags & MFI_FLAGS_QFRZN)
1826                         break;
1827
1828                 /* Try a command that has already been prepared */
1829                 cm = mfi_dequeue_ready(sc);
1830
1831                 if (cm == NULL) {
1832                         if ((ccbh = TAILQ_FIRST(&sc->mfi_cam_ccbq)) != NULL)
1833                                 cm = sc->mfi_cam_start(ccbh);
1834                 }
1835
1836                 /* Nope, so look for work on the bioq */
1837                 if (cm == NULL)
1838                         cm = mfi_bio_command(sc);
1839
1840                 /* No work available, so exit */
1841                 if (cm == NULL)
1842                         break;
1843
1844                 /* Send the command to the controller */
1845                 if (mfi_mapcmd(sc, cm) != 0) {
1846                         mfi_requeue_ready(cm);
1847                         break;
1848                 }
1849         }
1850 }
1851
1852 static int
1853 mfi_mapcmd(struct mfi_softc *sc, struct mfi_command *cm)
1854 {
1855         int error, polled;
1856
1857         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1858
1859         if (cm->cm_data != NULL) {
1860                 polled = (cm->cm_flags & MFI_CMD_POLLED) ? BUS_DMA_NOWAIT : 0;
1861                 error = bus_dmamap_load(sc->mfi_buffer_dmat, cm->cm_dmamap,
1862                     cm->cm_data, cm->cm_len, mfi_data_cb, cm, polled);
1863                 if (error == EINPROGRESS) {
1864                         sc->mfi_flags |= MFI_FLAGS_QFRZN;
1865                         return (0);
1866                 }
1867         } else {
1868                 error = mfi_send_frame(sc, cm);
1869         }
1870
1871         return (error);
1872 }
1873
1874 static void
1875 mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
1876 {
1877         struct mfi_frame_header *hdr;
1878         struct mfi_command *cm;
1879         union mfi_sgl *sgl;
1880         struct mfi_softc *sc;
1881         int i, j, first, dir;
1882         int sgl_mapped = 0;
1883         int sge_size = 0;
1884
1885         cm = (struct mfi_command *)arg;
1886         sc = cm->cm_sc;
1887         hdr = &cm->cm_frame->header;
1888         sgl = cm->cm_sg;
1889
1890         if (error) {
1891                 kprintf("error %d in callback\n", error);
1892                 cm->cm_error = error;
1893                 mfi_complete(sc, cm);
1894                 return;
1895         }
1896
1897         /* Use IEEE sgl only for IO's on a SKINNY controller
1898          * For other commands on a SKINNY controller use either
1899          * sg32 or sg64 based on the sizeof(bus_addr_t).
1900          * Also calculate the total frame size based on the type
1901          * of SGL used.
1902          */
1903         if (((cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) ||
1904              (cm->cm_frame->header.cmd == MFI_CMD_LD_READ) ||
1905              (cm->cm_frame->header.cmd == MFI_CMD_LD_WRITE)) &&
1906             (sc->mfi_flags & MFI_FLAGS_SKINNY)) {
1907                 for (i = 0; i < nsegs; i++) {
1908                         sgl->sg_skinny[i].addr = segs[i].ds_addr;
1909                         sgl->sg_skinny[i].len = segs[i].ds_len;
1910                         sgl->sg_skinny[i].flag = 0;
1911                 }
1912                 hdr->flags |= MFI_FRAME_IEEE_SGL | MFI_FRAME_SGL64;
1913                 sgl_mapped = 1;
1914                 sge_size = sizeof(struct mfi_sg_skinny);
1915         }
1916         if (!sgl_mapped) {
1917                 j = 0;
1918                 if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
1919                         first = cm->cm_stp_len;
1920                         if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
1921                                 sgl->sg32[j].addr = segs[0].ds_addr;
1922                                 sgl->sg32[j++].len = first;
1923                         } else {
1924                                 sgl->sg64[j].addr = segs[0].ds_addr;
1925                                 sgl->sg64[j++].len = first;
1926                         }
1927                 } else
1928                         first = 0;
1929                 if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
1930                         for (i = 0; i < nsegs; i++) {
1931                                 sgl->sg32[j].addr = segs[i].ds_addr + first;
1932                                 sgl->sg32[j++].len = segs[i].ds_len - first;
1933                                 first = 0;
1934                         }
1935                         sge_size = sizeof(struct mfi_sg32);
1936                 } else {
1937                         for (i = 0; i < nsegs; i++) {
1938                                 sgl->sg64[j].addr = segs[i].ds_addr + first;
1939                                 sgl->sg64[j++].len = segs[i].ds_len - first;
1940                                 first = 0;
1941                         }
1942                         hdr->flags |= MFI_FRAME_SGL64;
1943                         sge_size = sizeof(struct mfi_sg64);
1944                 }
1945                 hdr->sg_count = j;
1946         } else
1947                 hdr->sg_count = nsegs;
1948
1949         dir = 0;
1950         if (cm->cm_flags & MFI_CMD_DATAIN) {
1951                 dir |= BUS_DMASYNC_PREREAD;
1952                 hdr->flags |= MFI_FRAME_DIR_READ;
1953         }
1954         if (cm->cm_flags & MFI_CMD_DATAOUT) {
1955                 dir |= BUS_DMASYNC_PREWRITE;
1956                 hdr->flags |= MFI_FRAME_DIR_WRITE;
1957         }
1958         if (cm->cm_frame->header.cmd == MFI_CMD_STP)
1959                 dir |= BUS_DMASYNC_PREWRITE;
1960         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
1961         cm->cm_flags |= MFI_CMD_MAPPED;
1962
1963         /*
1964          * Instead of calculating the total number of frames in the
1965          * compound frame, it's already assumed that there will be at
1966          * least 1 frame, so don't compensate for the modulo of the
1967          * following division.
1968          */
1969         cm->cm_total_frame_size += (sge_size * nsegs);
1970         cm->cm_extra_frames = (cm->cm_total_frame_size - 1) / MFI_FRAME_SIZE;
1971
1972         mfi_send_frame(sc, cm);
1973 }
1974
1975 static int
1976 mfi_send_frame(struct mfi_softc *sc, struct mfi_command *cm)
1977 {
1978         struct mfi_frame_header *hdr;
1979         int tm = MFI_POLL_TIMEOUT_SECS * 1000;
1980
1981         hdr = &cm->cm_frame->header;
1982
1983         if ((cm->cm_flags & MFI_CMD_POLLED) == 0) {
1984                 cm->cm_timestamp = time_second;
1985                 mfi_enqueue_busy(cm);
1986         } else {
1987                 hdr->cmd_status = MFI_STAT_INVALID_STATUS;
1988                 hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
1989         }
1990
1991         /*
1992          * The bus address of the command is aligned on a 64 byte boundary,
1993          * leaving the least 6 bits as zero.  For whatever reason, the
1994          * hardware wants the address shifted right by three, leaving just
1995          * 3 zero bits.  These three bits are then used as a prefetching
1996          * hint for the hardware to predict how many frames need to be
1997          * fetched across the bus.  If a command has more than 8 frames
1998          * then the 3 bits are set to 0x7 and the firmware uses other
1999          * information in the command to determine the total amount to fetch.
2000          * However, FreeBSD doesn't support I/O larger than 128K, so 8 frames
2001          * is enough for both 32bit and 64bit systems.
2002          */
2003         if (cm->cm_extra_frames > 7)
2004                 cm->cm_extra_frames = 7;
2005
2006         sc->mfi_issue_cmd(sc,cm->cm_frame_busaddr,cm->cm_extra_frames);
2007
2008         if ((cm->cm_flags & MFI_CMD_POLLED) == 0)
2009                 return (0);
2010
2011         /* This is a polled command, so busy-wait for it to complete. */
2012         while (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
2013                 DELAY(1000);
2014                 tm -= 1;
2015                 if (tm <= 0)
2016                         break;
2017         }
2018
2019         if (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
2020                 device_printf(sc->mfi_dev, "Frame %p timed out "
2021                               "command 0x%X\n", hdr, cm->cm_frame->dcmd.opcode);
2022                 return (ETIMEDOUT);
2023         }
2024
2025         return (0);
2026 }
2027
2028 static void
2029 mfi_complete(struct mfi_softc *sc, struct mfi_command *cm)
2030 {
2031         int dir;
2032
2033         if ((cm->cm_flags & MFI_CMD_MAPPED) != 0) {
2034                 dir = 0;
2035                 if ((cm->cm_flags & MFI_CMD_DATAIN) ||
2036                     (cm->cm_frame->header.cmd == MFI_CMD_STP))
2037                         dir |= BUS_DMASYNC_POSTREAD;
2038                 if (cm->cm_flags & MFI_CMD_DATAOUT)
2039                         dir |= BUS_DMASYNC_POSTWRITE;
2040
2041                 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
2042                 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
2043                 cm->cm_flags &= ~MFI_CMD_MAPPED;
2044         }
2045
2046         cm->cm_flags |= MFI_CMD_COMPLETED;
2047
2048         if (cm->cm_complete != NULL)
2049                 cm->cm_complete(cm);
2050         else
2051                 wakeup(cm);
2052 }
2053
2054 static int
2055 mfi_abort(struct mfi_softc *sc, struct mfi_command *cm_abort)
2056 {
2057         struct mfi_command *cm;
2058         struct mfi_abort_frame *abort;
2059         int i = 0;
2060         uint32_t context = 0;
2061
2062         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
2063
2064         if ((cm = mfi_dequeue_free(sc)) == NULL) {
2065                 return (EBUSY);
2066         }
2067
2068         /* Zero out the MFI frame */
2069         context = cm->cm_frame->header.context;
2070         bzero(cm->cm_frame, sizeof(union mfi_frame));
2071         cm->cm_frame->header.context = context;
2072
2073         abort = &cm->cm_frame->abort;
2074         abort->header.cmd = MFI_CMD_ABORT;
2075         abort->header.flags = 0;
2076         abort->header.scsi_status = 0;
2077         abort->abort_context = cm_abort->cm_frame->header.context;
2078 #if defined(__x86_64__)
2079         abort->abort_mfi_addr_lo = cm_abort->cm_frame_busaddr & 0xFFFFFFFF;
2080         abort->abort_mfi_addr_hi = (cm_abort->cm_frame_busaddr & 0xFFFFFFFF00000000 ) >> 32  ;
2081 #else
2082         abort->abort_mfi_addr_lo = cm_abort->cm_frame_busaddr;
2083         abort->abort_mfi_addr_hi = 0;
2084 #endif
2085         cm->cm_data = NULL;
2086         cm->cm_flags = MFI_CMD_POLLED;
2087
2088         sc->mfi_aen_cm->cm_aen_abort = 1;
2089         mfi_mapcmd(sc, cm);
2090         mfi_release_command(cm);
2091
2092         while (i < 5 && sc->mfi_aen_cm != NULL) {
2093                 lksleep(&sc->mfi_aen_cm, &sc->mfi_io_lock, 0, "mfiabort", 5 * hz);
2094                 i++;
2095         }
2096
2097         return (0);
2098 }
2099
2100 int
2101 mfi_dump_blocks(struct mfi_softc *sc, int id, uint64_t lba, void *virt, int len)
2102 {
2103         struct mfi_command *cm;
2104         struct mfi_io_frame *io;
2105         int error;
2106         uint32_t context = 0;
2107
2108         if ((cm = mfi_dequeue_free(sc)) == NULL)
2109                 return (EBUSY);
2110
2111         /* Zero out the MFI frame */
2112         context = cm->cm_frame->header.context;
2113         bzero(cm->cm_frame, sizeof(union mfi_frame));
2114         cm->cm_frame->header.context = context;
2115
2116         io = &cm->cm_frame->io;
2117         io->header.cmd = MFI_CMD_LD_WRITE;
2118         io->header.target_id = id;
2119         io->header.timeout = 0;
2120         io->header.flags = 0;
2121         io->header.scsi_status = 0;
2122         io->header.sense_len = MFI_SENSE_LEN;
2123         io->header.data_len = (len + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
2124 #if defined(__x86_64__)
2125         io->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
2126         io->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000 ) >> 32;
2127 #else
2128         io->sense_addr_lo = cm->cm_sense_busaddr;
2129         io->sense_addr_hi = 0;
2130 #endif
2131         io->lba_hi = (lba & 0xffffffff00000000) >> 32;
2132         io->lba_lo = lba & 0xffffffff;
2133         cm->cm_data = virt;
2134         cm->cm_len = len;
2135         cm->cm_sg = &io->sgl;
2136         cm->cm_total_frame_size = MFI_IO_FRAME_SIZE;
2137         cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT;
2138
2139         error = mfi_mapcmd(sc, cm);
2140         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
2141             BUS_DMASYNC_POSTWRITE);
2142         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
2143         mfi_release_command(cm);
2144
2145         return (error);
2146 }
2147
2148 int
2149 mfi_dump_syspd_blocks(struct mfi_softc *sc, int id, uint64_t lba, void *virt,
2150     int len)
2151 {
2152         struct mfi_command *cm;
2153         struct mfi_pass_frame *pass;
2154         int error;
2155         int blkcount = 0;
2156
2157         if ((cm = mfi_dequeue_free(sc)) == NULL)
2158                 return (EBUSY);
2159
2160         pass = &cm->cm_frame->pass;
2161         bzero(pass->cdb, 16);
2162         pass->header.cmd = MFI_CMD_PD_SCSI_IO;
2163         pass->cdb[0] = WRITE_10;
2164         pass->cdb[2] = (lba & 0xff000000) >> 24;
2165         pass->cdb[3] = (lba & 0x00ff0000) >> 16;
2166         pass->cdb[4] = (lba & 0x0000ff00) >> 8;
2167         pass->cdb[5] = (lba & 0x000000ff);
2168         blkcount = (len + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
2169         pass->cdb[7] = (blkcount & 0xff00) >> 8;
2170         pass->cdb[8] = (blkcount & 0x00ff);
2171         pass->header.target_id = id;
2172         pass->header.timeout = 0;
2173         pass->header.flags = 0;
2174         pass->header.scsi_status = 0;
2175         pass->header.sense_len = MFI_SENSE_LEN;
2176         pass->header.data_len = len;
2177         pass->header.cdb_len = 10;
2178 #if defined(__x86_64__)
2179         pass->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
2180         pass->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000 ) >> 32;
2181 #else
2182         pass->sense_addr_lo = cm->cm_sense_busaddr;
2183         pass->sense_addr_hi = 0;
2184 #endif
2185         cm->cm_data = virt;
2186         cm->cm_len = len;
2187         cm->cm_sg = &pass->sgl;
2188         cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE;
2189         cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT;
2190
2191         error = mfi_mapcmd(sc, cm);
2192         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
2193             BUS_DMASYNC_POSTWRITE);
2194         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
2195         mfi_release_command(cm);
2196
2197         return (error);
2198 }
2199
2200 static int
2201 mfi_open(struct dev_open_args *ap)
2202 {
2203         cdev_t dev = ap->a_head.a_dev;
2204         struct mfi_softc *sc;
2205         int error;
2206
2207         sc = dev->si_drv1;
2208
2209         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2210         if (sc->mfi_detaching)
2211                 error = ENXIO;
2212         else {
2213                 sc->mfi_flags |= MFI_FLAGS_OPEN;
2214                 error = 0;
2215         }
2216         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2217
2218         return (error);
2219 }
2220
2221 static int
2222 mfi_close(struct dev_close_args *ap)
2223 {
2224         cdev_t dev = ap->a_head.a_dev;
2225         struct mfi_softc *sc;
2226         struct mfi_aen *mfi_aen_entry, *tmp;
2227
2228         sc = dev->si_drv1;
2229
2230         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2231         sc->mfi_flags &= ~MFI_FLAGS_OPEN;
2232
2233         TAILQ_FOREACH_MUTABLE(mfi_aen_entry, &sc->mfi_aen_pids, aen_link, tmp) {
2234                 if (mfi_aen_entry->p == curproc) {
2235                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
2236                             aen_link);
2237                         kfree(mfi_aen_entry, M_MFIBUF);
2238                 }
2239         }
2240         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2241         return (0);
2242 }
2243
2244 static int
2245 mfi_config_lock(struct mfi_softc *sc, uint32_t opcode)
2246 {
2247
2248         switch (opcode) {
2249         case MFI_DCMD_LD_DELETE:
2250         case MFI_DCMD_CFG_ADD:
2251         case MFI_DCMD_CFG_CLEAR:
2252                 lockmgr(&sc->mfi_config_lock, LK_EXCLUSIVE);
2253                 return (1);
2254         default:
2255                 return (0);
2256         }
2257 }
2258
2259 static void
2260 mfi_config_unlock(struct mfi_softc *sc, int locked)
2261 {
2262
2263         if (locked)
2264                 lockmgr(&sc->mfi_config_lock, LK_RELEASE);
2265 }
2266
2267 /* Perform pre-issue checks on commands from userland and possibly veto them. */
2268 static int
2269 mfi_check_command_pre(struct mfi_softc *sc, struct mfi_command *cm)
2270 {
2271         struct mfi_disk *ld, *ld2;
2272         int error;
2273         struct mfi_system_pd *syspd = NULL;
2274         uint16_t syspd_id;
2275         uint16_t *mbox;
2276
2277         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
2278         error = 0;
2279         switch (cm->cm_frame->dcmd.opcode) {
2280         case MFI_DCMD_LD_DELETE:
2281                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2282                         if (ld->ld_id == cm->cm_frame->dcmd.mbox[0])
2283                                 break;
2284                 }
2285                 if (ld == NULL)
2286                         error = ENOENT;
2287                 else
2288                         error = mfi_disk_disable(ld);
2289                 break;
2290         case MFI_DCMD_CFG_CLEAR:
2291                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2292                         error = mfi_disk_disable(ld);
2293                         if (error)
2294                                 break;
2295                 }
2296                 if (error) {
2297                         TAILQ_FOREACH(ld2, &sc->mfi_ld_tqh, ld_link) {
2298                                 if (ld2 == ld)
2299                                         break;
2300                                 mfi_disk_enable(ld2);
2301                         }
2302                 }
2303                 break;
2304         case MFI_DCMD_PD_STATE_SET:
2305                 mbox = (uint16_t *)cm->cm_frame->dcmd.mbox;
2306                 syspd_id = mbox[0];
2307                 if (mbox[2] == MFI_PD_STATE_UNCONFIGURED_GOOD) {
2308                         if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
2309                                 TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh, pd_link) {
2310                                         if (syspd->pd_id == syspd_id)
2311                                                 break;
2312                                 }
2313                         }
2314                 } else {
2315                         break;
2316                 }
2317                 if(syspd)
2318                         error = mfi_syspd_disable(syspd);
2319                 break;
2320         default:
2321                 break;
2322         }
2323         return (error);
2324 }
2325
2326 /* Perform post-issue checks on commands from userland. */
2327 static void
2328 mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm)
2329 {
2330         struct mfi_disk *ld, *ldn;
2331         struct mfi_system_pd *syspd = NULL;
2332         uint16_t syspd_id;
2333         uint16_t *mbox;
2334
2335         switch (cm->cm_frame->dcmd.opcode) {
2336         case MFI_DCMD_LD_DELETE:
2337                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2338                         if (ld->ld_id == cm->cm_frame->dcmd.mbox[0])
2339                                 break;
2340                 }
2341                 KASSERT(ld != NULL, ("volume dissappeared"));
2342                 if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) {
2343                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2344                         get_mplock();
2345                         device_delete_child(sc->mfi_dev, ld->ld_dev);
2346                         rel_mplock();
2347                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2348                 } else
2349                         mfi_disk_enable(ld);
2350                 break;
2351         case MFI_DCMD_CFG_CLEAR:
2352                 if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) {
2353                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2354                         get_mplock();
2355                         TAILQ_FOREACH_MUTABLE(ld, &sc->mfi_ld_tqh, ld_link, ldn) {
2356                                 device_delete_child(sc->mfi_dev, ld->ld_dev);
2357                         }
2358                         rel_mplock();
2359                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2360                 } else {
2361                         TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link)
2362                                 mfi_disk_enable(ld);
2363                 }
2364                 break;
2365         case MFI_DCMD_CFG_ADD:
2366                 mfi_ldprobe(sc);
2367                 break;
2368         case MFI_DCMD_CFG_FOREIGN_IMPORT:
2369                 mfi_ldprobe(sc);
2370                 break;
2371         case MFI_DCMD_PD_STATE_SET:
2372                 mbox = (uint16_t *)cm->cm_frame->dcmd.mbox;
2373                 syspd_id = mbox[0];
2374                 if (mbox[2] == MFI_PD_STATE_UNCONFIGURED_GOOD) {
2375                         if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
2376                                 TAILQ_FOREACH(syspd,&sc->mfi_syspd_tqh,pd_link) {
2377                                         if (syspd->pd_id == syspd_id)
2378                                                 break;
2379                                 }
2380                         }
2381                 } else {
2382                         break;
2383                 }
2384                 /* If the transition fails then enable the syspd again */
2385                 if(syspd && cm->cm_frame->header.cmd_status != MFI_STAT_OK)
2386                         mfi_syspd_enable(syspd);
2387                 break;
2388         }
2389 }
2390
2391 static int
2392 mfi_user_command(struct mfi_softc *sc, struct mfi_ioc_passthru *ioc)
2393 {
2394         struct mfi_command *cm;
2395         struct mfi_dcmd_frame *dcmd;
2396         void *ioc_buf = NULL;
2397         uint32_t context;
2398         int error = 0, locked;
2399
2400
2401         if (ioc->buf_size > 0) {
2402                 ioc_buf = kmalloc(ioc->buf_size, M_MFIBUF, M_WAITOK);
2403                 error = copyin(ioc->buf, ioc_buf, ioc->buf_size);
2404                 if (error) {
2405                         device_printf(sc->mfi_dev, "failed to copyin\n");
2406                         kfree(ioc_buf, M_MFIBUF);
2407                         return (error);
2408                 }
2409         }
2410
2411         locked = mfi_config_lock(sc, ioc->ioc_frame.opcode);
2412
2413         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2414         while ((cm = mfi_dequeue_free(sc)) == NULL)
2415                 lksleep(mfi_user_command, &sc->mfi_io_lock, 0, "mfiioc", hz);
2416
2417         /* Save context for later */
2418         context = cm->cm_frame->header.context;
2419
2420         dcmd = &cm->cm_frame->dcmd;
2421         bcopy(&ioc->ioc_frame, dcmd, sizeof(struct mfi_dcmd_frame));
2422
2423         cm->cm_sg = &dcmd->sgl;
2424         cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
2425         cm->cm_data = ioc_buf;
2426         cm->cm_len = ioc->buf_size;
2427
2428         /* restore context */
2429         cm->cm_frame->header.context = context;
2430
2431         /* Cheat since we don't know if we're writing or reading */
2432         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_DATAOUT;
2433
2434         error = mfi_check_command_pre(sc, cm);
2435         if (error)
2436                 goto out;
2437
2438         error = mfi_wait_command(sc, cm);
2439         if (error) {
2440                 device_printf(sc->mfi_dev, "ioctl failed %d\n", error);
2441                 goto out;
2442         }
2443         bcopy(dcmd, &ioc->ioc_frame, sizeof(struct mfi_dcmd_frame));
2444         mfi_check_command_post(sc, cm);
2445 out:
2446         mfi_release_command(cm);
2447         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2448         mfi_config_unlock(sc, locked);
2449         if (ioc->buf_size > 0)
2450                 error = copyout(ioc_buf, ioc->buf, ioc->buf_size);
2451         if (ioc_buf)
2452                 kfree(ioc_buf, M_MFIBUF);
2453         return (error);
2454 }
2455
2456 #ifdef __x86_64__
2457 #define PTRIN(p)                ((void *)(uintptr_t)(p))
2458 #else
2459 #define PTRIN(p)                (p)
2460 #endif
2461
2462 static int
2463 mfi_check_for_sscd(struct mfi_softc *sc, struct mfi_command *cm)
2464 {
2465         struct mfi_config_data *conf_data = cm->cm_data;
2466         struct mfi_command *ld_cm = NULL;
2467         struct mfi_ld_info *ld_info = NULL;
2468         int error = 0;
2469
2470         if ((cm->cm_frame->dcmd.opcode == MFI_DCMD_CFG_ADD) &&
2471             (conf_data->ld[0].params.isSSCD == 1)) {
2472                 error = 1;
2473         } else if (cm->cm_frame->dcmd.opcode == MFI_DCMD_LD_DELETE) {
2474                 error = mfi_dcmd_command(sc, &ld_cm, MFI_DCMD_LD_GET_INFO,
2475                     (void **)&ld_info, sizeof(*ld_info));
2476                 if (error) {
2477                         device_printf(sc->mfi_dev,"Failed to allocate "
2478                             "MFI_DCMD_LD_GET_INFO %d", error);
2479                         if (ld_info)
2480                                 kfree(ld_info, M_MFIBUF);
2481                         return 0;
2482                 }
2483                 ld_cm->cm_flags = MFI_CMD_DATAIN;
2484                 ld_cm->cm_frame->dcmd.mbox[0]= cm->cm_frame->dcmd.mbox[0];
2485                 ld_cm->cm_frame->header.target_id = cm->cm_frame->dcmd.mbox[0];
2486                 if (mfi_wait_command(sc, ld_cm) != 0) {
2487                         device_printf(sc->mfi_dev, "failed to get log drv\n");
2488                         mfi_release_command(ld_cm);
2489                         kfree(ld_info, M_MFIBUF);
2490                         return 0;
2491                 }
2492
2493                 if (ld_cm->cm_frame->header.cmd_status != MFI_STAT_OK) {
2494                         kfree(ld_info, M_MFIBUF);
2495                         mfi_release_command(ld_cm);
2496                         return 0;
2497                 } else {
2498                         ld_info = (struct mfi_ld_info *)ld_cm->cm_private;
2499                 }
2500
2501                 if (ld_info->ld_config.params.isSSCD == 1)
2502                         error = 1;
2503
2504                 mfi_release_command(ld_cm);
2505                 kfree(ld_info, M_MFIBUF);
2506         }
2507         return error;
2508 }
2509
2510 static int
2511 mfi_ioctl(struct dev_ioctl_args *ap)
2512 {
2513         cdev_t dev = ap->a_head.a_dev;
2514         u_long cmd = ap->a_cmd;
2515         int flag = ap->a_fflag;
2516         caddr_t arg = ap->a_data;
2517         struct mfi_softc *sc;
2518         union mfi_statrequest *ms;
2519         struct mfi_ioc_packet *ioc;
2520 #ifdef __x86_64__
2521         struct mfi_ioc_packet32 *ioc32;
2522 #endif
2523         struct mfi_ioc_aen *aen;
2524         struct mfi_command *cm = NULL;
2525         uint32_t context;
2526         union mfi_sense_ptr sense_ptr;
2527         uint8_t *data = NULL, *temp, *addr, skip_pre_post = 0;
2528         size_t len;
2529         int i;
2530         struct mfi_ioc_passthru *iop = (struct mfi_ioc_passthru *)arg;
2531 #ifdef __x86_64__
2532         struct mfi_ioc_passthru32 *iop32 = (struct mfi_ioc_passthru32 *)arg;
2533         struct mfi_ioc_passthru iop_swab;
2534 #endif
2535         int error, locked;
2536
2537         sc = dev->si_drv1;
2538         error = 0;
2539
2540         switch (cmd) {
2541         case MFIIO_STATS:
2542                 ms = (union mfi_statrequest *)arg;
2543                 switch (ms->ms_item) {
2544                 case MFIQ_FREE:
2545                 case MFIQ_BIO:
2546                 case MFIQ_READY:
2547                 case MFIQ_BUSY:
2548                         bcopy(&sc->mfi_qstat[ms->ms_item], &ms->ms_qstat,
2549                             sizeof(struct mfi_qstat));
2550                         break;
2551                 default:
2552                         error = ENOIOCTL;
2553                         break;
2554                 }
2555                 break;
2556         case MFIIO_QUERY_DISK:
2557         {
2558                 struct mfi_query_disk *qd;
2559                 struct mfi_disk *ld;
2560
2561                 qd = (struct mfi_query_disk *)arg;
2562                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2563                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2564                         if (ld->ld_id == qd->array_id)
2565                                 break;
2566                 }
2567                 if (ld == NULL) {
2568                         qd->present = 0;
2569                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2570                         return (0);
2571                 }
2572                 qd->present = 1;
2573                 if (ld->ld_flags & MFI_DISK_FLAGS_OPEN)
2574                         qd->open = 1;
2575                 bzero(qd->devname, SPECNAMELEN + 1);
2576                 ksnprintf(qd->devname, SPECNAMELEN, "mfid%d", ld->ld_unit);
2577                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2578                 break;
2579         }
2580         case MFI_CMD:
2581 #ifdef __x86_64__
2582         case MFI_CMD32:
2583 #endif
2584                 {
2585                 devclass_t devclass;
2586                 ioc = (struct mfi_ioc_packet *)arg;
2587                 int adapter;
2588
2589                 adapter = ioc->mfi_adapter_no;
2590                 if (device_get_unit(sc->mfi_dev) == 0 && adapter != 0) {
2591                         devclass = devclass_find("mfi");
2592                         sc = devclass_get_softc(devclass, adapter);
2593                 }
2594                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2595                 if ((cm = mfi_dequeue_free(sc)) == NULL) {
2596                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2597                         return (EBUSY);
2598                 }
2599                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2600                 locked = 0;
2601
2602                 /*
2603                  * save off original context since copying from user
2604                  * will clobber some data
2605                  */
2606                 context = cm->cm_frame->header.context;
2607
2608                 bcopy(ioc->mfi_frame.raw, cm->cm_frame,
2609                     2 * MFI_DCMD_FRAME_SIZE);  /* this isn't quite right */
2610                 cm->cm_total_frame_size = (sizeof(union mfi_sgl)
2611                     * ioc->mfi_sge_count) + ioc->mfi_sgl_off;
2612                 cm->cm_frame->header.scsi_status = 0;
2613                 cm->cm_frame->header.pad0 = 0;
2614                 if (ioc->mfi_sge_count) {
2615                         cm->cm_sg =
2616                             (union mfi_sgl *)&cm->cm_frame->bytes[ioc->mfi_sgl_off];
2617                 }
2618                 cm->cm_flags = 0;
2619                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAIN)
2620                         cm->cm_flags |= MFI_CMD_DATAIN;
2621                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAOUT)
2622                         cm->cm_flags |= MFI_CMD_DATAOUT;
2623                 /* Legacy app shim */
2624                 if (cm->cm_flags == 0)
2625                         cm->cm_flags |= MFI_CMD_DATAIN | MFI_CMD_DATAOUT;
2626                 cm->cm_len = cm->cm_frame->header.data_len;
2627                 if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
2628 #ifdef __x86_64__
2629                         if (cmd == MFI_CMD) {
2630 #endif
2631                                 /* Native */
2632                                 cm->cm_stp_len = ioc->mfi_sgl[0].iov_len;
2633 #ifdef __x86_64__
2634                         } else {
2635                                 /* 32bit on 64bit */
2636                                 ioc32 = (struct mfi_ioc_packet32 *)ioc;
2637                                 cm->cm_stp_len = ioc32->mfi_sgl[0].iov_len;
2638                         }
2639 #endif
2640                         cm->cm_len += cm->cm_stp_len;
2641                 }
2642                 if (cm->cm_len &&
2643                     (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) {
2644                         cm->cm_data = data = kmalloc(cm->cm_len, M_MFIBUF,
2645                             M_WAITOK | M_ZERO);
2646                 } else {
2647                         cm->cm_data = 0;
2648                 }
2649
2650                 /* restore header context */
2651                 cm->cm_frame->header.context = context;
2652
2653                 temp = data;
2654                 if ((cm->cm_flags & MFI_CMD_DATAOUT) ||
2655                     (cm->cm_frame->header.cmd == MFI_CMD_STP)) {
2656                         for (i = 0; i < ioc->mfi_sge_count; i++) {
2657 #ifdef __x86_64__
2658                                 if (cmd == MFI_CMD) {
2659 #endif
2660                                         /* Native */
2661                                         addr = ioc->mfi_sgl[i].iov_base;
2662                                         len = ioc->mfi_sgl[i].iov_len;
2663 #ifdef __x86_64__
2664                                 } else {
2665                                         /* 32bit on 64bit */
2666                                         ioc32 = (struct mfi_ioc_packet32 *)ioc;
2667                                         addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
2668                                         len = ioc32->mfi_sgl[i].iov_len;
2669                                 }
2670 #endif
2671                                 error = copyin(addr, temp, len);
2672                                 if (error != 0) {
2673                                         device_printf(sc->mfi_dev,
2674                                             "Copy in failed\n");
2675                                         goto out;
2676                                 }
2677                                 temp = &temp[len];
2678                         }
2679                 }
2680
2681                 if (cm->cm_frame->header.cmd == MFI_CMD_DCMD)
2682                         locked = mfi_config_lock(sc, cm->cm_frame->dcmd.opcode);
2683
2684                 if (cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) {
2685 #if defined(__x86_64__)
2686                         cm->cm_frame->pass.sense_addr_lo =
2687                             (cm->cm_sense_busaddr & 0xFFFFFFFF);
2688                         cm->cm_frame->pass.sense_addr_hi =
2689                             (cm->cm_sense_busaddr& 0xFFFFFFFF00000000) >> 32;
2690 #else
2691                         cm->cm_frame->pass.sense_addr_lo = cm->cm_sense_busaddr;
2692                         cm->cm_frame->pass.sense_addr_hi = 0;
2693 #endif
2694                 }
2695
2696                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2697                 skip_pre_post = mfi_check_for_sscd(sc, cm);
2698                 if (!skip_pre_post) {
2699                         error = mfi_check_command_pre(sc, cm);
2700                         if (error) {
2701                                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2702                                 goto out;
2703                         }
2704                 }
2705
2706                 if ((error = mfi_wait_command(sc, cm)) != 0) {
2707                         device_printf(sc->mfi_dev,
2708                             "Controller polled failed\n");
2709                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2710                         goto out;
2711                 }
2712
2713                 if (!skip_pre_post)
2714                         mfi_check_command_post(sc, cm);
2715                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2716
2717                 temp = data;
2718                 if ((cm->cm_flags & MFI_CMD_DATAIN) ||
2719                     (cm->cm_frame->header.cmd == MFI_CMD_STP)) {
2720                         for (i = 0; i < ioc->mfi_sge_count; i++) {
2721 #ifdef __x86_64__
2722                                 if (cmd == MFI_CMD) {
2723 #endif
2724                                         /* Native */
2725                                         addr = ioc->mfi_sgl[i].iov_base;
2726                                         len = ioc->mfi_sgl[i].iov_len;
2727 #ifdef __x86_64__
2728                                 } else {
2729                                         /* 32bit on 64bit */
2730                                         ioc32 = (struct mfi_ioc_packet32 *)ioc;
2731                                         addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
2732                                         len = ioc32->mfi_sgl[i].iov_len;
2733                                 }
2734 #endif
2735                                 error = copyout(temp, addr, len);
2736                                 if (error != 0) {
2737                                         device_printf(sc->mfi_dev,
2738                                             "Copy out failed\n");
2739                                         goto out;
2740                                 }
2741                                 temp = &temp[len];
2742                         }
2743                 }
2744
2745                 if (ioc->mfi_sense_len) {
2746                         /* get user-space sense ptr then copy out sense */
2747                         bcopy(&ioc->mfi_frame.raw[ioc->mfi_sense_off],
2748                             &sense_ptr.sense_ptr_data[0],
2749                             sizeof(sense_ptr.sense_ptr_data));
2750 #ifdef __x86_64__
2751                         if (cmd != MFI_CMD) {
2752                                 /*
2753                                  * not 64bit native so zero out any address
2754                                  * over 32bit */
2755                                 sense_ptr.addr.high = 0;
2756                         }
2757 #endif
2758                         error = copyout(cm->cm_sense, sense_ptr.user_space,
2759                             ioc->mfi_sense_len);
2760                         if (error != 0) {
2761                                 device_printf(sc->mfi_dev,
2762                                     "Copy out failed\n");
2763                                 goto out;
2764                         }
2765                 }
2766
2767                 ioc->mfi_frame.hdr.cmd_status = cm->cm_frame->header.cmd_status;
2768 out:
2769                 mfi_config_unlock(sc, locked);
2770                 if (data)
2771                         kfree(data, M_MFIBUF);
2772                 if (cm) {
2773                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2774                         mfi_release_command(cm);
2775                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2776                 }
2777
2778                 break;
2779                 }
2780         case MFI_SET_AEN:
2781                 aen = (struct mfi_ioc_aen *)arg;
2782                 error = mfi_aen_register(sc, aen->aen_seq_num,
2783                     aen->aen_class_locale);
2784
2785                 break;
2786         case MFI_LINUX_CMD_2: /* Firmware Linux ioctl shim */
2787                 {
2788                         devclass_t devclass;
2789                         struct mfi_linux_ioc_packet l_ioc;
2790                         int adapter;
2791
2792                         devclass = devclass_find("mfi");
2793                         if (devclass == NULL)
2794                                 return (ENOENT);
2795
2796                         error = copyin(arg, &l_ioc, sizeof(l_ioc));
2797                         if (error)
2798                                 return (error);
2799                         adapter = l_ioc.lioc_adapter_no;
2800                         sc = devclass_get_softc(devclass, adapter);
2801                         if (sc == NULL)
2802                                 return (ENOENT);
2803                         return (mfi_linux_ioctl_int(sc->mfi_cdev,
2804                             cmd, arg, flag));
2805                         break;
2806                 }
2807         case MFI_LINUX_SET_AEN_2: /* AEN Linux ioctl shim */
2808                 {
2809                         devclass_t devclass;
2810                         struct mfi_linux_ioc_aen l_aen;
2811                         int adapter;
2812
2813                         devclass = devclass_find("mfi");
2814                         if (devclass == NULL)
2815                                 return (ENOENT);
2816
2817                         error = copyin(arg, &l_aen, sizeof(l_aen));
2818                         if (error)
2819                                 return (error);
2820                         adapter = l_aen.laen_adapter_no;
2821                         sc = devclass_get_softc(devclass, adapter);
2822                         if (sc == NULL)
2823                                 return (ENOENT);
2824                         return (mfi_linux_ioctl_int(sc->mfi_cdev,
2825                             cmd, arg, flag));
2826                         break;
2827                 }
2828 #ifdef __x86_64__
2829         case MFIIO_PASSTHRU32:
2830                 iop_swab.ioc_frame      = iop32->ioc_frame;
2831                 iop_swab.buf_size       = iop32->buf_size;
2832                 iop_swab.buf            = PTRIN(iop32->buf);
2833                 iop                     = &iop_swab;
2834                 /* FALLTHROUGH */
2835 #endif
2836         case MFIIO_PASSTHRU:
2837                 error = mfi_user_command(sc, iop);
2838 #ifdef __x86_64__
2839                 if (cmd == MFIIO_PASSTHRU32)
2840                         iop32->ioc_frame = iop_swab.ioc_frame;
2841 #endif
2842                 break;
2843         default:
2844                 device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd);
2845                 error = ENOENT;
2846                 break;
2847         }
2848
2849         return (error);
2850 }
2851
2852 static int
2853 mfi_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t arg, int flag)
2854 {
2855         struct mfi_softc *sc;
2856         struct mfi_linux_ioc_packet l_ioc;
2857         struct mfi_linux_ioc_aen l_aen;
2858         struct mfi_command *cm = NULL;
2859         struct mfi_aen *mfi_aen_entry;
2860         union mfi_sense_ptr sense_ptr;
2861         uint32_t context;
2862         uint8_t *data = NULL, *temp;
2863         int i;
2864         int error, locked;
2865
2866         sc = dev->si_drv1;
2867         error = 0;
2868         switch (cmd) {
2869         case MFI_LINUX_CMD_2: /* Firmware Linux ioctl shim */
2870                 error = copyin(arg, &l_ioc, sizeof(l_ioc));
2871                 if (error != 0)
2872                         return (error);
2873
2874                 if (l_ioc.lioc_sge_count > MAX_LINUX_IOCTL_SGE) {
2875                         return (EINVAL);
2876                 }
2877
2878                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2879                 if ((cm = mfi_dequeue_free(sc)) == NULL) {
2880                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2881                         return (EBUSY);
2882                 }
2883                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2884                 locked = 0;
2885
2886                 /*
2887                  * save off original context since copying from user
2888                  * will clobber some data
2889                  */
2890                 context = cm->cm_frame->header.context;
2891
2892                 bcopy(l_ioc.lioc_frame.raw, cm->cm_frame,
2893                       2 * MFI_DCMD_FRAME_SIZE); /* this isn't quite right */
2894                 cm->cm_total_frame_size = (sizeof(union mfi_sgl)
2895                       * l_ioc.lioc_sge_count) + l_ioc.lioc_sgl_off;
2896                 cm->cm_frame->header.scsi_status = 0;
2897                 cm->cm_frame->header.pad0 = 0;
2898                 if (l_ioc.lioc_sge_count)
2899                         cm->cm_sg =
2900                             (union mfi_sgl *)&cm->cm_frame->bytes[l_ioc.lioc_sgl_off];
2901                 cm->cm_flags = 0;
2902                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAIN)
2903                         cm->cm_flags |= MFI_CMD_DATAIN;
2904                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAOUT)
2905                         cm->cm_flags |= MFI_CMD_DATAOUT;
2906                 cm->cm_len = cm->cm_frame->header.data_len;
2907                 if (cm->cm_len &&
2908                       (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) {
2909                         cm->cm_data = data = kmalloc(cm->cm_len, M_MFIBUF,
2910                             M_WAITOK | M_ZERO);
2911                 } else {
2912                         cm->cm_data = 0;
2913                 }
2914
2915                 /* restore header context */
2916                 cm->cm_frame->header.context = context;
2917
2918                 temp = data;
2919                 if (cm->cm_flags & MFI_CMD_DATAOUT) {
2920                         for (i = 0; i < l_ioc.lioc_sge_count; i++) {
2921                                 error = copyin(PTRIN(l_ioc.lioc_sgl[i].iov_base),
2922                                        temp,
2923                                        l_ioc.lioc_sgl[i].iov_len);
2924                                 if (error != 0) {
2925                                         device_printf(sc->mfi_dev,
2926                                             "Copy in failed\n");
2927                                         goto out;
2928                                 }
2929                                 temp = &temp[l_ioc.lioc_sgl[i].iov_len];
2930                         }
2931                 }
2932
2933                 if (cm->cm_frame->header.cmd == MFI_CMD_DCMD)
2934                         locked = mfi_config_lock(sc, cm->cm_frame->dcmd.opcode);
2935
2936                 if (cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) {
2937 #if defined(__x86_64__)
2938                         cm->cm_frame->pass.sense_addr_lo =
2939                             (cm->cm_sense_busaddr & 0xFFFFFFFF);
2940                         cm->cm_frame->pass.sense_addr_hi =
2941                             (cm->cm_sense_busaddr & 0xFFFFFFFF00000000) >> 32;
2942 #else
2943                         cm->cm_frame->pass.sense_addr_lo = cm->cm_sense_busaddr;
2944                         cm->cm_frame->pass.sense_addr_hi = 0;
2945 #endif
2946                 }
2947
2948                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2949                 error = mfi_check_command_pre(sc, cm);
2950                 if (error) {
2951                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2952                         goto out;
2953                 }
2954
2955                 if ((error = mfi_wait_command(sc, cm)) != 0) {
2956                         device_printf(sc->mfi_dev,
2957                             "Controller polled failed\n");
2958                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2959                         goto out;
2960                 }
2961
2962                 mfi_check_command_post(sc, cm);
2963                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2964
2965                 temp = data;
2966                 if (cm->cm_flags & MFI_CMD_DATAIN) {
2967                         for (i = 0; i < l_ioc.lioc_sge_count; i++) {
2968                                 error = copyout(temp,
2969                                         PTRIN(l_ioc.lioc_sgl[i].iov_base),
2970                                         l_ioc.lioc_sgl[i].iov_len);
2971                                 if (error != 0) {
2972                                         device_printf(sc->mfi_dev,
2973                                             "Copy out failed\n");
2974                                         goto out;
2975                                 }
2976                                 temp = &temp[l_ioc.lioc_sgl[i].iov_len];
2977                         }
2978                 }
2979
2980                 if (l_ioc.lioc_sense_len) {
2981                         /* get user-space sense ptr then copy out sense */
2982                         bcopy(&((struct mfi_linux_ioc_packet*)arg)
2983                             ->lioc_frame.raw[l_ioc.lioc_sense_off],
2984                             &sense_ptr.sense_ptr_data[0],
2985                             sizeof(sense_ptr.sense_ptr_data));
2986 #ifdef __x86_64__
2987                         /*
2988                          * only 32bit Linux support so zero out any
2989                          * address over 32bit
2990                          */
2991                         sense_ptr.addr.high = 0;
2992 #endif
2993                         error = copyout(cm->cm_sense, sense_ptr.user_space,
2994                             l_ioc.lioc_sense_len);
2995                         if (error != 0) {
2996                                 device_printf(sc->mfi_dev,
2997                                     "Copy out failed\n");
2998                                 goto out;
2999                         }
3000                 }
3001
3002                 error = copyout(&cm->cm_frame->header.cmd_status,
3003                         &((struct mfi_linux_ioc_packet*)arg)
3004                         ->lioc_frame.hdr.cmd_status,
3005                         1);
3006                 if (error != 0) {
3007                         device_printf(sc->mfi_dev,
3008                                       "Copy out failed\n");
3009                         goto out;
3010                 }
3011
3012 out:
3013                 mfi_config_unlock(sc, locked);
3014                 if (data)
3015                         kfree(data, M_MFIBUF);
3016                 if (cm) {
3017                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3018                         mfi_release_command(cm);
3019                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3020                 }
3021
3022                 return (error);
3023         case MFI_LINUX_SET_AEN_2: /* AEN Linux ioctl shim */
3024                 error = copyin(arg, &l_aen, sizeof(l_aen));
3025                 if (error != 0)
3026                         return (error);
3027                 kprintf("AEN IMPLEMENTED for pid %d\n", curproc->p_pid);
3028                 mfi_aen_entry = kmalloc(sizeof(struct mfi_aen), M_MFIBUF,
3029                     M_WAITOK);
3030                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3031                 if (mfi_aen_entry != NULL) {
3032                         mfi_aen_entry->p = curproc;
3033                         TAILQ_INSERT_TAIL(&sc->mfi_aen_pids, mfi_aen_entry,
3034                             aen_link);
3035                 }
3036                 error = mfi_aen_register(sc, l_aen.laen_seq_num,
3037                     l_aen.laen_class_locale);
3038
3039                 if (error != 0) {
3040                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
3041                             aen_link);
3042                         kfree(mfi_aen_entry, M_MFIBUF);
3043                 }
3044                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3045
3046                 return (error);
3047         default:
3048                 device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd);
3049                 error = ENOENT;
3050                 break;
3051         }
3052
3053         return (error);
3054 }
3055
3056 static int
3057 mfi_kqfilter(struct dev_kqfilter_args *ap)
3058 {
3059         cdev_t dev = ap->a_head.a_dev;
3060         struct knote *kn = ap->a_kn;
3061         struct mfi_softc *sc;
3062         struct klist *klist;
3063
3064         ap->a_result = 0;
3065         sc = dev->si_drv1;
3066
3067         switch (kn->kn_filter) {
3068         case EVFILT_READ:
3069                 kn->kn_fop = &mfi_read_filterops;
3070                 kn->kn_hook = (caddr_t)sc;
3071                 break;
3072         case EVFILT_WRITE:
3073                 kn->kn_fop = &mfi_write_filterops;
3074                 kn->kn_hook = (caddr_t)sc;
3075                 break;
3076         default:
3077                 ap->a_result = EOPNOTSUPP;
3078                 return (0);
3079         }
3080
3081         klist = &sc->mfi_kq.ki_note;
3082         knote_insert(klist, kn);
3083
3084         return(0);
3085 }
3086
3087 static void
3088 mfi_filter_detach(struct knote *kn)
3089 {
3090         struct mfi_softc *sc = (struct mfi_softc *)kn->kn_hook;
3091         struct klist *klist = &sc->mfi_kq.ki_note;
3092
3093         knote_remove(klist, kn);
3094 }
3095
3096 static int
3097 mfi_filter_read(struct knote *kn, long hint)
3098 {
3099         struct mfi_softc *sc = (struct mfi_softc *)kn->kn_hook;
3100         int ready = 0;
3101
3102         if (sc->mfi_aen_triggered != 0) {
3103                 ready = 1;
3104                 sc->mfi_aen_triggered = 0;
3105         }
3106         if (sc->mfi_aen_triggered == 0 && sc->mfi_aen_cm == NULL)
3107                 kn->kn_flags |= EV_ERROR;
3108
3109         if (ready == 0)
3110                 sc->mfi_poll_waiting = 1;
3111
3112         return (ready);
3113 }
3114
3115 static int
3116 mfi_filter_write(struct knote *kn, long hint)
3117 {
3118         return (0);
3119 }
3120
3121 static void
3122 mfi_dump_all(void)
3123 {
3124         struct mfi_softc *sc;
3125         struct mfi_command *cm;
3126         devclass_t dc;
3127         time_t deadline;
3128         int timedout;
3129         int i;
3130
3131         dc = devclass_find("mfi");
3132         if (dc == NULL) {
3133                 kprintf("No mfi dev class\n");
3134                 return;
3135         }
3136
3137         for (i = 0; ; i++) {
3138                 sc = devclass_get_softc(dc, i);
3139                 if (sc == NULL)
3140                         break;
3141                 device_printf(sc->mfi_dev, "Dumping\n\n");
3142                 timedout = 0;
3143                 deadline = time_second - MFI_CMD_TIMEOUT;
3144                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3145                 TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {
3146                         if (cm->cm_timestamp < deadline) {
3147                                 device_printf(sc->mfi_dev,
3148                                     "COMMAND %p TIMEOUT AFTER %d SECONDS\n", cm,
3149                                     (int)(time_second - cm->cm_timestamp));
3150                                 MFI_PRINT_CMD(cm);
3151                                 timedout++;
3152                         }
3153                 }
3154
3155 #if 0
3156                 if (timedout)
3157                         MFI_DUMP_CMDS(SC);
3158 #endif
3159
3160                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3161         }
3162
3163         return;
3164 }
3165
3166 static void
3167 mfi_timeout(void *data)
3168 {
3169         struct mfi_softc *sc = (struct mfi_softc *)data;
3170         struct mfi_command *cm;
3171         time_t deadline;
3172         int timedout = 0;
3173
3174         deadline = time_second - MFI_CMD_TIMEOUT;
3175         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3176         TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {
3177                 if (sc->mfi_aen_cm == cm)
3178                         continue;
3179                 if ((sc->mfi_aen_cm != cm) && (cm->cm_timestamp < deadline)) {
3180                         device_printf(sc->mfi_dev,
3181                             "COMMAND %p TIMEOUT AFTER %d SECONDS\n", cm,
3182                             (int)(time_second - cm->cm_timestamp));
3183                         MFI_PRINT_CMD(cm);
3184                         MFI_VALIDATE_CMD(sc, cm);
3185                         timedout++;
3186                 }
3187         }
3188
3189 #if 0
3190         if (timedout)
3191                 MFI_DUMP_CMDS(SC);
3192 #endif
3193
3194         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3195
3196         callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,
3197             mfi_timeout, sc);
3198
3199         if (0)
3200                 mfi_dump_all();
3201         return;
3202 }