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