Merge branch 'vendor/TNFTP'
[dragonfly.git] / sys / dev / raid / mfi / mfi.c
1 /*-
2  * Copyright (c) 2006 IronPort Systems
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 /*-
27  * Copyright (c) 2007 LSI Corp.
28  * Copyright (c) 2007 Rajesh Prabhakaran.
29  * All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  * 1. Redistributions of source code must retain the above copyright
35  *    notice, this list of conditions and the following disclaimer.
36  * 2. Redistributions in binary form must reproduce the above copyright
37  *    notice, this list of conditions and the following disclaimer in the
38  *    documentation and/or other materials provided with the distribution.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  */
52 /*-
53  * Redistribution and use in source and binary forms, with or without
54  * modification, are permitted provided that the following conditions
55  * are met:
56  *
57  *            Copyright 1994-2009 The FreeBSD Project.
58  *            All rights reserved.
59  *
60  * 1. Redistributions of source code must retain the above copyright
61  *    notice, this list of conditions and the following disclaimer.
62  * 2. Redistributions in binary form must reproduce the above copyright
63  *    notice, this list of conditions and the following disclaimer in the
64  *    documentation and/or other materials provided with the distribution.
65  *
66  *    THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT``AS IS'' AND
67  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
68  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
69  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FREEBSD PROJECT OR
70  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
71  * EXEMPLARY,OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
72  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
73  * PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY THEORY
74  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
75  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77  *
78  * The views and conclusions contained in the software and documentation
79  * are those of the authors and should not be interpreted as representing
80  * official policies,either expressed or implied, of the FreeBSD Project.
81  *
82  * $FreeBSD: src/sys/dev/mfi/mfi.c,v 1.62 2011/11/09 21:53:49 delphij Exp $
83  */
84
85 #include "opt_mfi.h"
86
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/sysctl.h>
90 #include <sys/malloc.h>
91 #include <sys/kernel.h>
92 #include <sys/bus.h>
93 #include <sys/eventhandler.h>
94 #include <sys/rman.h>
95 #include <sys/bus_dma.h>
96 #include <sys/buf2.h>
97 #include <sys/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_mp(&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         if (mtx_initialized(&sc->mfi_io_lock))
1018 #endif
1019         {
1020         lockuninit(&sc->mfi_io_lock);
1021         lockuninit(&sc->mfi_config_lock);
1022         }
1023
1024         return;
1025 }
1026
1027 static void
1028 mfi_startup(void *arg)
1029 {
1030         struct mfi_softc *sc;
1031
1032         sc = (struct mfi_softc *)arg;
1033
1034         config_intrhook_disestablish(&sc->mfi_ich);
1035
1036         sc->mfi_enable_intr(sc);
1037         lockmgr(&sc->mfi_config_lock, LK_EXCLUSIVE);
1038         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1039         mfi_ldprobe(sc);
1040         if (sc->mfi_flags & MFI_FLAGS_SKINNY)
1041                 mfi_syspdprobe(sc);
1042         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1043         lockmgr(&sc->mfi_config_lock, LK_RELEASE);
1044 }
1045
1046 static void
1047 mfi_intr(void *arg)
1048 {
1049         struct mfi_softc *sc;
1050         struct mfi_command *cm;
1051         uint32_t pi, ci, context;
1052
1053         sc = (struct mfi_softc *)arg;
1054
1055         if (sc->mfi_check_clear_intr(sc))
1056                 return;
1057
1058         /*
1059          * Do a dummy read to flush the interrupt ACK that we just performed,
1060          * ensuring that everything is really, truly consistent.
1061          */
1062         (void)sc->mfi_read_fw_status(sc);
1063
1064         pi = sc->mfi_comms->hw_pi;
1065         ci = sc->mfi_comms->hw_ci;
1066         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1067         while (ci != pi) {
1068                 context = sc->mfi_comms->hw_reply_q[ci];
1069                 if (context < sc->mfi_max_fw_cmds) {
1070                         cm = &sc->mfi_commands[context];
1071                         mfi_remove_busy(cm);
1072                         cm->cm_error = 0;
1073                         mfi_complete(sc, cm);
1074                 }
1075                 if (++ci == (sc->mfi_max_fw_cmds + 1)) {
1076                         ci = 0;
1077                 }
1078         }
1079
1080         sc->mfi_comms->hw_ci = ci;
1081
1082         /* Give defered I/O a chance to run */
1083         if (sc->mfi_flags & MFI_FLAGS_QFRZN)
1084                 sc->mfi_flags &= ~MFI_FLAGS_QFRZN;
1085         mfi_startio(sc);
1086         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1087
1088         return;
1089 }
1090
1091 int
1092 mfi_shutdown(struct mfi_softc *sc)
1093 {
1094         struct mfi_dcmd_frame *dcmd;
1095         struct mfi_command *cm;
1096         int error;
1097
1098         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1099         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_SHUTDOWN, NULL, 0);
1100         if (error) {
1101                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1102                 return (error);
1103         }
1104
1105         if (sc->mfi_aen_cm != NULL)
1106                 mfi_abort(sc, sc->mfi_aen_cm);
1107
1108         dcmd = &cm->cm_frame->dcmd;
1109         dcmd->header.flags = MFI_FRAME_DIR_NONE;
1110         cm->cm_flags = MFI_CMD_POLLED;
1111         cm->cm_data = NULL;
1112
1113         if ((error = mfi_mapcmd(sc, cm)) != 0) {
1114                 device_printf(sc->mfi_dev, "Failed to shutdown controller\n");
1115         }
1116
1117         mfi_release_command(cm);
1118         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1119         return (error);
1120 }
1121 static void
1122 mfi_syspdprobe(struct mfi_softc *sc)
1123 {
1124         struct mfi_frame_header *hdr;
1125         struct mfi_command *cm = NULL;
1126         struct mfi_pd_list *pdlist = NULL;
1127         struct mfi_system_pd *syspd;
1128         int error, i;
1129
1130         KKASSERT(lockstatus(&sc->mfi_config_lock, curthread) != 0);
1131         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1132         /* Add SYSTEM PD's */
1133         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_PD_LIST_QUERY,
1134             (void **)&pdlist, sizeof(*pdlist));
1135         if (error) {
1136                 device_printf(sc->mfi_dev,"Error while forming syspd list\n");
1137                 goto out;
1138         }
1139
1140         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
1141         cm->cm_frame->dcmd.mbox[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
1142         cm->cm_frame->dcmd.mbox[1] = 0;
1143         if (mfi_mapcmd(sc, cm) != 0) {
1144                 device_printf(sc->mfi_dev, "Failed to get syspd device list\n");
1145                 goto out;
1146         }
1147         bus_dmamap_sync(sc->mfi_buffer_dmat,cm->cm_dmamap,
1148             BUS_DMASYNC_POSTREAD);
1149         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
1150         hdr = &cm->cm_frame->header;
1151         if (hdr->cmd_status != MFI_STAT_OK) {
1152                 device_printf(sc->mfi_dev, "MFI_DCMD_PD_LIST_QUERY failed %x\n",
1153                     hdr->cmd_status);
1154                 goto out;
1155         }
1156         for (i = 0; i < pdlist->count; i++) {
1157                 if (pdlist->addr[i].device_id == pdlist->addr[i].encl_device_id)
1158                         goto skip_sys_pd_add;
1159                 /* Get each PD and add it to the system */
1160                 if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
1161                         TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh,pd_link) {
1162                                 if (syspd->pd_id == pdlist->addr[i].device_id)
1163                                         goto skip_sys_pd_add;
1164                         }
1165                 }
1166                 mfi_add_sys_pd(sc,pdlist->addr[i].device_id);
1167 skip_sys_pd_add:
1168                 ;
1169         }
1170         /* Delete SYSPD's whose state has been changed */
1171         if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
1172                 TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh,pd_link) {
1173                         for (i=0;i<pdlist->count;i++) {
1174                                 if (syspd->pd_id == pdlist->addr[i].device_id)
1175                                         goto skip_sys_pd_delete;
1176                         }
1177                         get_mplock();
1178                         device_delete_child(sc->mfi_dev,syspd->pd_dev);
1179                         rel_mplock();
1180 skip_sys_pd_delete:
1181                         ;
1182                 }
1183         }
1184 out:
1185         if (pdlist)
1186                 kfree(pdlist, M_MFIBUF);
1187         if (cm)
1188                 mfi_release_command(cm);
1189 }
1190
1191 static void
1192 mfi_ldprobe(struct mfi_softc *sc)
1193 {
1194         struct mfi_frame_header *hdr;
1195         struct mfi_command *cm = NULL;
1196         struct mfi_ld_list *list = NULL;
1197         struct mfi_disk *ld;
1198         int error, i;
1199
1200         KKASSERT(lockstatus(&sc->mfi_config_lock, curthread) != 0);
1201         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1202
1203         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_LIST,
1204             (void **)&list, sizeof(*list));
1205         if (error)
1206                 goto out;
1207
1208         cm->cm_flags = MFI_CMD_DATAIN;
1209         if (mfi_wait_command(sc, cm) != 0) {
1210                 device_printf(sc->mfi_dev, "Failed to get device listing\n");
1211                 goto out;
1212         }
1213
1214         hdr = &cm->cm_frame->header;
1215         if (hdr->cmd_status != MFI_STAT_OK) {
1216                 device_printf(sc->mfi_dev, "MFI_DCMD_LD_GET_LIST failed %x\n",
1217                     hdr->cmd_status);
1218                 goto out;
1219         }
1220
1221         for (i = 0; i < list->ld_count; i++) {
1222                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
1223                         if (ld->ld_id == list->ld_list[i].ld.v.target_id)
1224                                 goto skip_add;
1225                 }
1226                 mfi_add_ld(sc, list->ld_list[i].ld.v.target_id);
1227         skip_add:;
1228         }
1229 out:
1230         if (list)
1231                 kfree(list, M_MFIBUF);
1232         if (cm)
1233                 mfi_release_command(cm);
1234
1235         return;
1236 }
1237
1238 /*
1239  * The timestamp is the number of seconds since 00:00 Jan 1, 2000.  If
1240  * the bits in 24-31 are all set, then it is the number of seconds since
1241  * boot.
1242  */
1243 static const char *
1244 format_timestamp(uint32_t timestamp)
1245 {
1246         static char buffer[32];
1247
1248         if ((timestamp & 0xff000000) == 0xff000000)
1249                 ksnprintf(buffer, sizeof(buffer), "boot + %us", timestamp &
1250                     0x00ffffff);
1251         else
1252                 ksnprintf(buffer, sizeof(buffer), "%us", timestamp);
1253         return (buffer);
1254 }
1255
1256 static const char *
1257 format_class(int8_t class)
1258 {
1259         static char buffer[6];
1260
1261         switch (class) {
1262         case MFI_EVT_CLASS_DEBUG:
1263                 return ("debug");
1264         case MFI_EVT_CLASS_PROGRESS:
1265                 return ("progress");
1266         case MFI_EVT_CLASS_INFO:
1267                 return ("info");
1268         case MFI_EVT_CLASS_WARNING:
1269                 return ("WARN");
1270         case MFI_EVT_CLASS_CRITICAL:
1271                 return ("CRIT");
1272         case MFI_EVT_CLASS_FATAL:
1273                 return ("FATAL");
1274         case MFI_EVT_CLASS_DEAD:
1275                 return ("DEAD");
1276         default:
1277                 ksnprintf(buffer, sizeof(buffer), "%d", class);
1278                 return (buffer);
1279         }
1280 }
1281
1282 static void
1283 mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail)
1284 {
1285
1286         device_printf(sc->mfi_dev, "%d (%s/0x%04x/%s) - %s\n", detail->seq,
1287             format_timestamp(detail->time), detail->evt_class.members.locale,
1288             format_class(detail->evt_class.members.evt_class), detail->description);
1289 }
1290
1291 static int
1292 mfi_aen_register(struct mfi_softc *sc, int seq, int locale)
1293 {
1294         struct mfi_command *cm;
1295         struct mfi_dcmd_frame *dcmd;
1296         union mfi_evt current_aen, prior_aen;
1297         struct mfi_evt_detail *ed = NULL;
1298         int error = 0;
1299
1300         current_aen.word = locale;
1301         if (sc->mfi_aen_cm != NULL) {
1302                 prior_aen.word =
1303                     ((uint32_t *)&sc->mfi_aen_cm->cm_frame->dcmd.mbox)[1];
1304                 if (prior_aen.members.evt_class <= current_aen.members.evt_class &&
1305                     !((prior_aen.members.locale & current_aen.members.locale)
1306                     ^current_aen.members.locale)) {
1307                         return (0);
1308                 } else {
1309                         prior_aen.members.locale |= current_aen.members.locale;
1310                         if (prior_aen.members.evt_class
1311                             < current_aen.members.evt_class)
1312                                 current_aen.members.evt_class =
1313                                     prior_aen.members.evt_class;
1314                         mfi_abort(sc, sc->mfi_aen_cm);
1315                 }
1316         }
1317
1318         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_WAIT,
1319             (void **)&ed, sizeof(*ed));
1320         if (error) {
1321                 goto out;
1322         }
1323
1324         dcmd = &cm->cm_frame->dcmd;
1325         ((uint32_t *)&dcmd->mbox)[0] = seq;
1326         ((uint32_t *)&dcmd->mbox)[1] = locale;
1327         cm->cm_flags = MFI_CMD_DATAIN;
1328         cm->cm_complete = mfi_aen_complete;
1329
1330         sc->mfi_aen_cm = cm;
1331
1332         mfi_enqueue_ready(cm);
1333         mfi_startio(sc);
1334
1335 out:
1336         return (error);
1337 }
1338
1339 static void
1340 mfi_aen_complete(struct mfi_command *cm)
1341 {
1342         struct mfi_frame_header *hdr;
1343         struct mfi_softc *sc;
1344         struct mfi_evt_detail *detail;
1345         struct mfi_aen *mfi_aen_entry, *tmp;
1346         int seq = 0, aborted = 0;
1347
1348         sc = cm->cm_sc;
1349         hdr = &cm->cm_frame->header;
1350
1351         if (sc->mfi_aen_cm == NULL)
1352                 return;
1353
1354         if (sc->mfi_aen_cm->cm_aen_abort ||
1355             hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
1356                 sc->mfi_aen_cm->cm_aen_abort = 0;
1357                 aborted = 1;
1358         } else {
1359                 sc->mfi_aen_triggered = 1;
1360                 if (sc->mfi_poll_waiting) {
1361                         sc->mfi_poll_waiting = 0;
1362                         KNOTE(&sc->mfi_kq.ki_note, 0);
1363                 }
1364                 detail = cm->cm_data;
1365                 /*
1366                  * XXX If this function is too expensive or is recursive, then
1367                  * events should be put onto a queue and processed later.
1368                  */
1369                 mfi_decode_evt(sc, detail);
1370                 seq = detail->seq + 1;
1371                 TAILQ_FOREACH_MUTABLE(mfi_aen_entry, &sc->mfi_aen_pids, aen_link, tmp) {
1372                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
1373                             aen_link);
1374                         lwkt_gettoken(&proc_token);
1375                         ksignal(mfi_aen_entry->p, SIGIO);
1376                         lwkt_reltoken(&proc_token);
1377                         kfree(mfi_aen_entry, M_MFIBUF);
1378                 }
1379         }
1380
1381         kfree(cm->cm_data, M_MFIBUF);
1382         sc->mfi_aen_cm = NULL;
1383         wakeup(&sc->mfi_aen_cm);
1384         mfi_release_command(cm);
1385
1386         /* set it up again so the driver can catch more events */
1387         if (!aborted) {
1388                 mfi_aen_setup(sc, seq);
1389         }
1390 }
1391
1392 #define MAX_EVENTS 15
1393
1394 static int
1395 mfi_parse_entries(struct mfi_softc *sc, int start_seq, int stop_seq)
1396 {
1397         struct mfi_command *cm;
1398         struct mfi_dcmd_frame *dcmd;
1399         struct mfi_evt_list *el;
1400         union mfi_evt class_locale;
1401         int error, i, seq, size;
1402         uint32_t context = 0;
1403
1404         class_locale.members.reserved = 0;
1405         class_locale.members.locale = mfi_event_locale;
1406         class_locale.members.evt_class  = mfi_event_class;
1407
1408         size = sizeof(struct mfi_evt_list) + sizeof(struct mfi_evt_detail)
1409                 * (MAX_EVENTS - 1);
1410         el = kmalloc(size, M_MFIBUF, M_NOWAIT | M_ZERO);
1411         if (el == NULL)
1412                 return (ENOMEM);
1413
1414         for (seq = start_seq;;) {
1415                 if ((cm = mfi_dequeue_free(sc)) == NULL) {
1416                         kfree(el, M_MFIBUF);
1417                         return (EBUSY);
1418                 }
1419
1420                 /* Zero out the MFI frame */
1421                 context = cm->cm_frame->header.context;
1422                 bzero(cm->cm_frame, sizeof(union mfi_frame));
1423                 cm->cm_frame->header.context = context;
1424
1425                 dcmd = &cm->cm_frame->dcmd;
1426                 bzero(dcmd->mbox, MFI_MBOX_SIZE);
1427                 dcmd->header.cmd = MFI_CMD_DCMD;
1428                 dcmd->header.timeout = 0;
1429                 dcmd->header.data_len = size;
1430                 dcmd->header.scsi_status = 0;
1431                 dcmd->opcode = MFI_DCMD_CTRL_EVENT_GET;
1432                 ((uint32_t *)&dcmd->mbox)[0] = seq;
1433                 ((uint32_t *)&dcmd->mbox)[1] = class_locale.word;
1434                 cm->cm_sg = &dcmd->sgl;
1435                 cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
1436                 cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
1437                 cm->cm_data = el;
1438                 cm->cm_len = size;
1439
1440                 if ((error = mfi_mapcmd(sc, cm)) != 0) {
1441                         device_printf(sc->mfi_dev,
1442                             "Failed to get controller entries\n");
1443                         mfi_release_command(cm);
1444                         break;
1445                 }
1446
1447                 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
1448                     BUS_DMASYNC_POSTREAD);
1449                 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
1450
1451                 if (dcmd->header.cmd_status == MFI_STAT_NOT_FOUND) {
1452                         mfi_release_command(cm);
1453                         break;
1454                 }
1455                 if (dcmd->header.cmd_status != MFI_STAT_OK) {
1456                         device_printf(sc->mfi_dev,
1457                             "Error %d fetching controller entries\n",
1458                             dcmd->header.cmd_status);
1459                         mfi_release_command(cm);
1460                         break;
1461                 }
1462                 mfi_release_command(cm);
1463
1464                 for (i = 0; i < el->count; i++) {
1465                         /*
1466                          * If this event is newer than 'stop_seq' then
1467                          * break out of the loop.  Note that the log
1468                          * is a circular buffer so we have to handle
1469                          * the case that our stop point is earlier in
1470                          * the buffer than our start point.
1471                          */
1472                         if (el->event[i].seq >= stop_seq) {
1473                                 if (start_seq <= stop_seq)
1474                                         break;
1475                                 else if (el->event[i].seq < start_seq)
1476                                         break;
1477                         }
1478                         mfi_decode_evt(sc, &el->event[i]);
1479                 }
1480                 seq = el->event[el->count - 1].seq + 1;
1481         }
1482
1483         kfree(el, M_MFIBUF);
1484         return (0);
1485 }
1486
1487 static int
1488 mfi_add_ld(struct mfi_softc *sc, int id)
1489 {
1490         struct mfi_command *cm;
1491         struct mfi_dcmd_frame *dcmd = NULL;
1492         struct mfi_ld_info *ld_info = NULL;
1493         int error;
1494
1495         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1496
1497         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_INFO,
1498             (void **)&ld_info, sizeof(*ld_info));
1499         if (error) {
1500                 device_printf(sc->mfi_dev,
1501                     "Failed to allocate for MFI_DCMD_LD_GET_INFO %d\n", error);
1502                 if (ld_info)
1503                         kfree(ld_info, M_MFIBUF);
1504                 return (error);
1505         }
1506         cm->cm_flags = MFI_CMD_DATAIN;
1507         dcmd = &cm->cm_frame->dcmd;
1508         dcmd->mbox[0] = id;
1509         if (mfi_wait_command(sc, cm) != 0) {
1510                 device_printf(sc->mfi_dev,
1511                     "Failed to get logical drive: %d\n", id);
1512                 kfree(ld_info, M_MFIBUF);
1513                 return (0);
1514         }
1515         if (ld_info->ld_config.params.isSSCD != 1) {
1516                 mfi_add_ld_complete(cm);
1517         } else {
1518                 mfi_release_command(cm);
1519                 if(ld_info)             /* SSCD drives ld_info free here */
1520                         kfree(ld_info, M_MFIBUF);
1521         }
1522         return (0);
1523 }
1524
1525 static void
1526 mfi_add_ld_complete(struct mfi_command *cm)
1527 {
1528         struct mfi_frame_header *hdr;
1529         struct mfi_ld_info *ld_info;
1530         struct mfi_softc *sc;
1531         device_t child;
1532
1533         sc = cm->cm_sc;
1534         hdr = &cm->cm_frame->header;
1535         ld_info = cm->cm_private;
1536
1537         if (hdr->cmd_status != MFI_STAT_OK) {
1538                 kfree(ld_info, M_MFIBUF);
1539                 mfi_release_command(cm);
1540                 return;
1541         }
1542         mfi_release_command(cm);
1543
1544         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1545         get_mplock();
1546         if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) {
1547                 device_printf(sc->mfi_dev, "Failed to add logical disk\n");
1548                 kfree(ld_info, M_MFIBUF);
1549                 rel_mplock();
1550                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1551                 return;
1552         }
1553
1554         device_set_ivars(child, ld_info);
1555         device_set_desc(child, "MFI Logical Disk");
1556         bus_generic_attach(sc->mfi_dev);
1557         rel_mplock();
1558         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1559 }
1560
1561 static int
1562 mfi_add_sys_pd(struct mfi_softc *sc,int id)
1563 {
1564         struct mfi_command *cm;
1565         struct mfi_dcmd_frame *dcmd = NULL;
1566         struct mfi_pd_info *pd_info = NULL;
1567         int error;
1568
1569         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1570
1571         error = mfi_dcmd_command(sc,&cm,MFI_DCMD_PD_GET_INFO,
1572             (void **)&pd_info, sizeof(*pd_info));
1573         if (error) {
1574                 device_printf(sc->mfi_dev,
1575                     "Failed to allocated for MFI_DCMD_PD_GET_INFO %d\n", error);
1576                 if (pd_info)
1577                         kfree(pd_info,M_MFIBUF);
1578                 return (error);
1579         }
1580         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
1581         dcmd = &cm->cm_frame->dcmd;
1582         dcmd->mbox[0] = id;
1583         dcmd->header.scsi_status = 0;
1584         dcmd->header.pad0 = 0;
1585         if (mfi_mapcmd(sc, cm) != 0) {
1586                 device_printf(sc->mfi_dev,
1587                     "Failed to get physical drive info %d\n", id);
1588                 kfree(pd_info,M_MFIBUF);
1589                 return (0);
1590         }
1591         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
1592             BUS_DMASYNC_POSTREAD);
1593         bus_dmamap_unload(sc->mfi_buffer_dmat,cm->cm_dmamap);
1594         mfi_add_sys_pd_complete(cm);
1595         return (0);
1596 }
1597
1598 static void
1599 mfi_add_sys_pd_complete(struct mfi_command *cm)
1600 {
1601         struct mfi_frame_header *hdr;
1602         struct mfi_pd_info *pd_info;
1603         struct mfi_softc *sc;
1604         device_t child;
1605
1606         sc = cm->cm_sc;
1607         hdr = &cm->cm_frame->header;
1608         pd_info = cm->cm_private;
1609
1610         if (hdr->cmd_status != MFI_STAT_OK) {
1611                 kfree(pd_info, M_MFIBUF);
1612                 mfi_release_command(cm);
1613                 return;
1614         }
1615         if (pd_info->fw_state != MFI_PD_STATE_SYSTEM) {
1616                 device_printf(sc->mfi_dev,"PD=%x is not SYSTEM PD\n",
1617                     pd_info->ref.v.device_id);
1618                 kfree(pd_info, M_MFIBUF);
1619                 mfi_release_command(cm);
1620                 return;
1621         }
1622         mfi_release_command(cm);
1623
1624         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
1625         get_mplock();
1626         if ((child = device_add_child(sc->mfi_dev, "mfisyspd", -1)) == NULL) {
1627                 device_printf(sc->mfi_dev, "Failed to add system pd\n");
1628                 kfree(pd_info, M_MFIBUF);
1629                 rel_mplock();
1630                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1631                 return;
1632         }
1633
1634         device_set_ivars(child, pd_info);
1635         device_set_desc(child, "MFI System PD");
1636         bus_generic_attach(sc->mfi_dev);
1637         rel_mplock();
1638         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
1639 }
1640
1641 static struct mfi_command *
1642 mfi_bio_command(struct mfi_softc *sc)
1643 {
1644         struct bio *bio;
1645         struct mfi_command *cm = NULL;
1646         struct mfi_disk *mfid;
1647
1648         /* reserving two commands to avoid starvation for IOCTL */
1649         if (sc->mfi_qstat[MFIQ_FREE].q_length < 2)
1650                 return (NULL);
1651         if ((bio = mfi_dequeue_bio(sc)) == NULL)
1652                 return (NULL);
1653         mfid = bio->bio_driver_info;
1654         if (mfid->ld_flags & MFI_DISK_FLAGS_SYSPD)
1655                 cm = mfi_build_syspdio(sc, bio);
1656         else
1657                 cm = mfi_build_ldio(sc, bio);
1658         if (!cm)
1659                 mfi_enqueue_bio(sc,bio);
1660         return cm;
1661 }
1662
1663 static struct mfi_command *
1664 mfi_build_syspdio(struct mfi_softc *sc, struct bio *bio)
1665 {
1666         struct mfi_command *cm;
1667         struct buf *bp;
1668         struct mfi_system_pd *disk;
1669         struct mfi_pass_frame *pass;
1670         int flags = 0,blkcount = 0;
1671         uint32_t context = 0;
1672
1673         if ((cm = mfi_dequeue_free(sc)) == NULL)
1674                 return (NULL);
1675
1676         /* Zero out the MFI frame */
1677         context = cm->cm_frame->header.context;
1678         bzero(cm->cm_frame, sizeof(union mfi_frame));
1679         cm->cm_frame->header.context = context;
1680         bp = bio->bio_buf;
1681         pass = &cm->cm_frame->pass;
1682         bzero(pass->cdb, 16);
1683         pass->header.cmd = MFI_CMD_PD_SCSI_IO;
1684         switch (bp->b_cmd & 0x03) {
1685         case BUF_CMD_READ:
1686                 pass->cdb[0] = READ_10;
1687                 flags = MFI_CMD_DATAIN;
1688                 break;
1689         case BUF_CMD_WRITE:
1690                 pass->cdb[0] = WRITE_10;
1691                 flags = MFI_CMD_DATAOUT;
1692                 break;
1693         default:
1694                 panic("Invalid bio command");
1695         }
1696
1697         /* Cheat with the sector length to avoid a non-constant division */
1698         blkcount = (bp->b_bcount + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
1699         disk = bio->bio_driver_info;
1700         /* Fill the LBA and Transfer length in CDB */
1701         pass->cdb[2] = ((bio->bio_offset / MFI_SECTOR_LEN) & 0xff000000) >> 24;
1702         pass->cdb[3] = ((bio->bio_offset / MFI_SECTOR_LEN) & 0x00ff0000) >> 16;
1703         pass->cdb[4] = ((bio->bio_offset / MFI_SECTOR_LEN) & 0x0000ff00) >> 8;
1704         pass->cdb[5] = (bio->bio_offset / MFI_SECTOR_LEN) & 0x000000ff;
1705         pass->cdb[7] = (blkcount & 0xff00) >> 8;
1706         pass->cdb[8] = (blkcount & 0x00ff);
1707         pass->header.target_id = disk->pd_id;
1708         pass->header.timeout = 0;
1709         pass->header.flags = 0;
1710         pass->header.scsi_status = 0;
1711         pass->header.sense_len = MFI_SENSE_LEN;
1712         pass->header.data_len = bp->b_bcount;
1713         pass->header.cdb_len = 10;
1714 #if defined(__x86_64__)
1715         pass->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
1716         pass->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000) >> 32;
1717 #else
1718         pass->sense_addr_lo = cm->cm_sense_busaddr;
1719         pass->sense_addr_hi = 0;
1720 #endif
1721         cm->cm_complete = mfi_bio_complete;
1722         cm->cm_private = bio;
1723         cm->cm_data = bp->b_data;
1724         cm->cm_len = bp->b_bcount;
1725         cm->cm_sg = &pass->sgl;
1726         cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE;
1727         cm->cm_flags = flags;
1728         return (cm);
1729 }
1730
1731 static struct mfi_command *
1732 mfi_build_ldio(struct mfi_softc *sc,struct bio *bio)
1733 {
1734         struct mfi_io_frame *io;
1735         struct buf *bp;
1736         struct mfi_disk *disk;
1737         struct mfi_command *cm;
1738         int flags, blkcount;
1739         uint32_t context = 0;
1740
1741         if ((cm = mfi_dequeue_free(sc)) == NULL)
1742             return (NULL);
1743
1744         /* Zero out the MFI frame */
1745         context = cm->cm_frame->header.context;
1746         bzero(cm->cm_frame,sizeof(union mfi_frame));
1747         cm->cm_frame->header.context = context;
1748         bp = bio->bio_buf;
1749         io = &cm->cm_frame->io;
1750         switch (bp->b_cmd & 0x03) {
1751         case BUF_CMD_READ:
1752                 io->header.cmd = MFI_CMD_LD_READ;
1753                 flags = MFI_CMD_DATAIN;
1754                 break;
1755         case BUF_CMD_WRITE:
1756                 io->header.cmd = MFI_CMD_LD_WRITE;
1757                 flags = MFI_CMD_DATAOUT;
1758                 break;
1759         default:
1760                 panic("Invalid bio command");
1761         }
1762
1763         /* Cheat with the sector length to avoid a non-constant division */
1764         blkcount = (bp->b_bcount + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
1765         disk = bio->bio_driver_info;
1766         io->header.target_id = disk->ld_id;
1767         io->header.timeout = 0;
1768         io->header.flags = 0;
1769         io->header.scsi_status = 0;
1770         io->header.sense_len = MFI_SENSE_LEN;
1771         io->header.data_len = blkcount;
1772 #if defined(__x86_64__)
1773         io->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
1774         io->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000) >> 32;
1775 #else
1776         io->sense_addr_lo = cm->cm_sense_busaddr;
1777         io->sense_addr_hi = 0;
1778 #endif
1779         io->lba_hi = ((bio->bio_offset / MFI_SECTOR_LEN) & 0xffffffff00000000) >> 32;
1780         io->lba_lo = (bio->bio_offset / MFI_SECTOR_LEN) & 0xffffffff;
1781         cm->cm_complete = mfi_bio_complete;
1782         cm->cm_private = bio;
1783         cm->cm_data = bp->b_data;
1784         cm->cm_len = bp->b_bcount;
1785         cm->cm_sg = &io->sgl;
1786         cm->cm_total_frame_size = MFI_IO_FRAME_SIZE;
1787         cm->cm_flags = flags;
1788         return (cm);
1789 }
1790
1791 static void
1792 mfi_bio_complete(struct mfi_command *cm)
1793 {
1794         struct bio *bio;
1795         struct buf *bp;
1796         struct mfi_frame_header *hdr;
1797         struct mfi_softc *sc;
1798
1799         bio = cm->cm_private;
1800         bp = bio->bio_buf;
1801         hdr = &cm->cm_frame->header;
1802         sc = cm->cm_sc;
1803
1804         if ((hdr->cmd_status != MFI_STAT_OK) || (hdr->scsi_status != 0)) {
1805                 bp->b_flags |= B_ERROR;
1806                 bp->b_error = EIO;
1807                 device_printf(sc->mfi_dev, "I/O error, status= %d "
1808                     "scsi_status= %d\n", hdr->cmd_status, hdr->scsi_status);
1809                 mfi_print_sense(cm->cm_sc, cm->cm_sense);
1810         } else if (cm->cm_error != 0) {
1811                 bp->b_flags |= B_ERROR;
1812         }
1813
1814         mfi_release_command(cm);
1815         mfi_disk_complete(bio);
1816 }
1817
1818 void
1819 mfi_startio(struct mfi_softc *sc)
1820 {
1821         struct mfi_command *cm;
1822         struct ccb_hdr *ccbh;
1823
1824         for (;;) {
1825                 /* Don't bother if we're short on resources */
1826                 if (sc->mfi_flags & MFI_FLAGS_QFRZN)
1827                         break;
1828
1829                 /* Try a command that has already been prepared */
1830                 cm = mfi_dequeue_ready(sc);
1831
1832                 if (cm == NULL) {
1833                         if ((ccbh = TAILQ_FIRST(&sc->mfi_cam_ccbq)) != NULL)
1834                                 cm = sc->mfi_cam_start(ccbh);
1835                 }
1836
1837                 /* Nope, so look for work on the bioq */
1838                 if (cm == NULL)
1839                         cm = mfi_bio_command(sc);
1840
1841                 /* No work available, so exit */
1842                 if (cm == NULL)
1843                         break;
1844
1845                 /* Send the command to the controller */
1846                 if (mfi_mapcmd(sc, cm) != 0) {
1847                         mfi_requeue_ready(cm);
1848                         break;
1849                 }
1850         }
1851 }
1852
1853 static int
1854 mfi_mapcmd(struct mfi_softc *sc, struct mfi_command *cm)
1855 {
1856         int error, polled;
1857
1858         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
1859
1860         if (cm->cm_data != NULL) {
1861                 polled = (cm->cm_flags & MFI_CMD_POLLED) ? BUS_DMA_NOWAIT : 0;
1862                 error = bus_dmamap_load(sc->mfi_buffer_dmat, cm->cm_dmamap,
1863                     cm->cm_data, cm->cm_len, mfi_data_cb, cm, polled);
1864                 if (error == EINPROGRESS) {
1865                         sc->mfi_flags |= MFI_FLAGS_QFRZN;
1866                         return (0);
1867                 }
1868         } else {
1869                 error = mfi_send_frame(sc, cm);
1870         }
1871
1872         return (error);
1873 }
1874
1875 static void
1876 mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
1877 {
1878         struct mfi_frame_header *hdr;
1879         struct mfi_command *cm;
1880         union mfi_sgl *sgl;
1881         struct mfi_softc *sc;
1882         int i, j, first, dir;
1883         int sgl_mapped = 0;
1884         int sge_size = 0;
1885
1886         cm = (struct mfi_command *)arg;
1887         sc = cm->cm_sc;
1888         hdr = &cm->cm_frame->header;
1889         sgl = cm->cm_sg;
1890
1891         if (error) {
1892                 kprintf("error %d in callback\n", error);
1893                 cm->cm_error = error;
1894                 mfi_complete(sc, cm);
1895                 return;
1896         }
1897
1898         /* Use IEEE sgl only for IO's on a SKINNY controller
1899          * For other commands on a SKINNY controller use either
1900          * sg32 or sg64 based on the sizeof(bus_addr_t).
1901          * Also calculate the total frame size based on the type
1902          * of SGL used.
1903          */
1904         if (((cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) ||
1905              (cm->cm_frame->header.cmd == MFI_CMD_LD_READ) ||
1906              (cm->cm_frame->header.cmd == MFI_CMD_LD_WRITE)) &&
1907             (sc->mfi_flags & MFI_FLAGS_SKINNY)) {
1908                 for (i = 0; i < nsegs; i++) {
1909                         sgl->sg_skinny[i].addr = segs[i].ds_addr;
1910                         sgl->sg_skinny[i].len = segs[i].ds_len;
1911                         sgl->sg_skinny[i].flag = 0;
1912                 }
1913                 hdr->flags |= MFI_FRAME_IEEE_SGL | MFI_FRAME_SGL64;
1914                 sgl_mapped = 1;
1915                 sge_size = sizeof(struct mfi_sg_skinny);
1916         }
1917         if (!sgl_mapped) {
1918                 j = 0;
1919                 if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
1920                         first = cm->cm_stp_len;
1921                         if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
1922                                 sgl->sg32[j].addr = segs[0].ds_addr;
1923                                 sgl->sg32[j++].len = first;
1924                         } else {
1925                                 sgl->sg64[j].addr = segs[0].ds_addr;
1926                                 sgl->sg64[j++].len = first;
1927                         }
1928                 } else
1929                         first = 0;
1930                 if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
1931                         for (i = 0; i < nsegs; i++) {
1932                                 sgl->sg32[j].addr = segs[i].ds_addr + first;
1933                                 sgl->sg32[j++].len = segs[i].ds_len - first;
1934                                 first = 0;
1935                         }
1936                         sge_size = sizeof(struct mfi_sg32);
1937                 } else {
1938                         for (i = 0; i < nsegs; i++) {
1939                                 sgl->sg64[j].addr = segs[i].ds_addr + first;
1940                                 sgl->sg64[j++].len = segs[i].ds_len - first;
1941                                 first = 0;
1942                         }
1943                         hdr->flags |= MFI_FRAME_SGL64;
1944                         sge_size = sizeof(struct mfi_sg64);
1945                 }
1946                 hdr->sg_count = j;
1947         } else
1948                 hdr->sg_count = nsegs;
1949
1950         dir = 0;
1951         if (cm->cm_flags & MFI_CMD_DATAIN) {
1952                 dir |= BUS_DMASYNC_PREREAD;
1953                 hdr->flags |= MFI_FRAME_DIR_READ;
1954         }
1955         if (cm->cm_flags & MFI_CMD_DATAOUT) {
1956                 dir |= BUS_DMASYNC_PREWRITE;
1957                 hdr->flags |= MFI_FRAME_DIR_WRITE;
1958         }
1959         if (cm->cm_frame->header.cmd == MFI_CMD_STP)
1960                 dir |= BUS_DMASYNC_PREWRITE;
1961         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
1962         cm->cm_flags |= MFI_CMD_MAPPED;
1963
1964         /*
1965          * Instead of calculating the total number of frames in the
1966          * compound frame, it's already assumed that there will be at
1967          * least 1 frame, so don't compensate for the modulo of the
1968          * following division.
1969          */
1970         cm->cm_total_frame_size += (sge_size * nsegs);
1971         cm->cm_extra_frames = (cm->cm_total_frame_size - 1) / MFI_FRAME_SIZE;
1972
1973         mfi_send_frame(sc, cm);
1974 }
1975
1976 static int
1977 mfi_send_frame(struct mfi_softc *sc, struct mfi_command *cm)
1978 {
1979         struct mfi_frame_header *hdr;
1980         int tm = MFI_POLL_TIMEOUT_SECS * 1000;
1981
1982         hdr = &cm->cm_frame->header;
1983
1984         if ((cm->cm_flags & MFI_CMD_POLLED) == 0) {
1985                 cm->cm_timestamp = time_second;
1986                 mfi_enqueue_busy(cm);
1987         } else {
1988                 hdr->cmd_status = MFI_STAT_INVALID_STATUS;
1989                 hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
1990         }
1991
1992         /*
1993          * The bus address of the command is aligned on a 64 byte boundary,
1994          * leaving the least 6 bits as zero.  For whatever reason, the
1995          * hardware wants the address shifted right by three, leaving just
1996          * 3 zero bits.  These three bits are then used as a prefetching
1997          * hint for the hardware to predict how many frames need to be
1998          * fetched across the bus.  If a command has more than 8 frames
1999          * then the 3 bits are set to 0x7 and the firmware uses other
2000          * information in the command to determine the total amount to fetch.
2001          * However, FreeBSD doesn't support I/O larger than 128K, so 8 frames
2002          * is enough for both 32bit and 64bit systems.
2003          */
2004         if (cm->cm_extra_frames > 7)
2005                 cm->cm_extra_frames = 7;
2006
2007         sc->mfi_issue_cmd(sc,cm->cm_frame_busaddr,cm->cm_extra_frames);
2008
2009         if ((cm->cm_flags & MFI_CMD_POLLED) == 0)
2010                 return (0);
2011
2012         /* This is a polled command, so busy-wait for it to complete. */
2013         while (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
2014                 DELAY(1000);
2015                 tm -= 1;
2016                 if (tm <= 0)
2017                         break;
2018         }
2019
2020         if (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
2021                 device_printf(sc->mfi_dev, "Frame %p timed out "
2022                               "command 0x%X\n", hdr, cm->cm_frame->dcmd.opcode);
2023                 return (ETIMEDOUT);
2024         }
2025
2026         return (0);
2027 }
2028
2029 static void
2030 mfi_complete(struct mfi_softc *sc, struct mfi_command *cm)
2031 {
2032         int dir;
2033
2034         if ((cm->cm_flags & MFI_CMD_MAPPED) != 0) {
2035                 dir = 0;
2036                 if ((cm->cm_flags & MFI_CMD_DATAIN) ||
2037                     (cm->cm_frame->header.cmd == MFI_CMD_STP))
2038                         dir |= BUS_DMASYNC_POSTREAD;
2039                 if (cm->cm_flags & MFI_CMD_DATAOUT)
2040                         dir |= BUS_DMASYNC_POSTWRITE;
2041
2042                 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
2043                 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
2044                 cm->cm_flags &= ~MFI_CMD_MAPPED;
2045         }
2046
2047         cm->cm_flags |= MFI_CMD_COMPLETED;
2048
2049         if (cm->cm_complete != NULL)
2050                 cm->cm_complete(cm);
2051         else
2052                 wakeup(cm);
2053 }
2054
2055 static int
2056 mfi_abort(struct mfi_softc *sc, struct mfi_command *cm_abort)
2057 {
2058         struct mfi_command *cm;
2059         struct mfi_abort_frame *abort;
2060         int i = 0;
2061         uint32_t context = 0;
2062
2063         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
2064
2065         if ((cm = mfi_dequeue_free(sc)) == NULL) {
2066                 return (EBUSY);
2067         }
2068
2069         /* Zero out the MFI frame */
2070         context = cm->cm_frame->header.context;
2071         bzero(cm->cm_frame, sizeof(union mfi_frame));
2072         cm->cm_frame->header.context = context;
2073
2074         abort = &cm->cm_frame->abort;
2075         abort->header.cmd = MFI_CMD_ABORT;
2076         abort->header.flags = 0;
2077         abort->header.scsi_status = 0;
2078         abort->abort_context = cm_abort->cm_frame->header.context;
2079 #if defined(__x86_64__)
2080         abort->abort_mfi_addr_lo = cm_abort->cm_frame_busaddr & 0xFFFFFFFF;
2081         abort->abort_mfi_addr_hi = (cm_abort->cm_frame_busaddr & 0xFFFFFFFF00000000 ) >> 32  ;
2082 #else
2083         abort->abort_mfi_addr_lo = cm_abort->cm_frame_busaddr;
2084         abort->abort_mfi_addr_hi = 0;
2085 #endif
2086         cm->cm_data = NULL;
2087         cm->cm_flags = MFI_CMD_POLLED;
2088
2089         sc->mfi_aen_cm->cm_aen_abort = 1;
2090         mfi_mapcmd(sc, cm);
2091         mfi_release_command(cm);
2092
2093         while (i < 5 && sc->mfi_aen_cm != NULL) {
2094                 lksleep(&sc->mfi_aen_cm, &sc->mfi_io_lock, 0, "mfiabort", 5 * hz);
2095                 i++;
2096         }
2097
2098         return (0);
2099 }
2100
2101 int
2102 mfi_dump_blocks(struct mfi_softc *sc, int id, uint64_t lba, void *virt, int len)
2103 {
2104         struct mfi_command *cm;
2105         struct mfi_io_frame *io;
2106         int error;
2107         uint32_t context = 0;
2108
2109         if ((cm = mfi_dequeue_free(sc)) == NULL)
2110                 return (EBUSY);
2111
2112         /* Zero out the MFI frame */
2113         context = cm->cm_frame->header.context;
2114         bzero(cm->cm_frame, sizeof(union mfi_frame));
2115         cm->cm_frame->header.context = context;
2116
2117         io = &cm->cm_frame->io;
2118         io->header.cmd = MFI_CMD_LD_WRITE;
2119         io->header.target_id = id;
2120         io->header.timeout = 0;
2121         io->header.flags = 0;
2122         io->header.scsi_status = 0;
2123         io->header.sense_len = MFI_SENSE_LEN;
2124         io->header.data_len = (len + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
2125 #if defined(__x86_64__)
2126         io->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
2127         io->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000 ) >> 32;
2128 #else
2129         io->sense_addr_lo = cm->cm_sense_busaddr;
2130         io->sense_addr_hi = 0;
2131 #endif
2132         io->lba_hi = (lba & 0xffffffff00000000) >> 32;
2133         io->lba_lo = lba & 0xffffffff;
2134         cm->cm_data = virt;
2135         cm->cm_len = len;
2136         cm->cm_sg = &io->sgl;
2137         cm->cm_total_frame_size = MFI_IO_FRAME_SIZE;
2138         cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT;
2139
2140         error = mfi_mapcmd(sc, cm);
2141         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
2142             BUS_DMASYNC_POSTWRITE);
2143         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
2144         mfi_release_command(cm);
2145
2146         return (error);
2147 }
2148
2149 int
2150 mfi_dump_syspd_blocks(struct mfi_softc *sc, int id, uint64_t lba, void *virt,
2151     int len)
2152 {
2153         struct mfi_command *cm;
2154         struct mfi_pass_frame *pass;
2155         int error;
2156         int blkcount = 0;
2157
2158         if ((cm = mfi_dequeue_free(sc)) == NULL)
2159                 return (EBUSY);
2160
2161         pass = &cm->cm_frame->pass;
2162         bzero(pass->cdb, 16);
2163         pass->header.cmd = MFI_CMD_PD_SCSI_IO;
2164         pass->cdb[0] = WRITE_10;
2165         pass->cdb[2] = (lba & 0xff000000) >> 24;
2166         pass->cdb[3] = (lba & 0x00ff0000) >> 16;
2167         pass->cdb[4] = (lba & 0x0000ff00) >> 8;
2168         pass->cdb[5] = (lba & 0x000000ff);
2169         blkcount = (len + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
2170         pass->cdb[7] = (blkcount & 0xff00) >> 8;
2171         pass->cdb[8] = (blkcount & 0x00ff);
2172         pass->header.target_id = id;
2173         pass->header.timeout = 0;
2174         pass->header.flags = 0;
2175         pass->header.scsi_status = 0;
2176         pass->header.sense_len = MFI_SENSE_LEN;
2177         pass->header.data_len = len;
2178         pass->header.cdb_len = 10;
2179 #if defined(__x86_64__)
2180         pass->sense_addr_lo = (cm->cm_sense_busaddr & 0xFFFFFFFF);
2181         pass->sense_addr_hi = (cm->cm_sense_busaddr & 0xFFFFFFFF00000000 ) >> 32;
2182 #else
2183         pass->sense_addr_lo = cm->cm_sense_busaddr;
2184         pass->sense_addr_hi = 0;
2185 #endif
2186         cm->cm_data = virt;
2187         cm->cm_len = len;
2188         cm->cm_sg = &pass->sgl;
2189         cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE;
2190         cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT;
2191
2192         error = mfi_mapcmd(sc, cm);
2193         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
2194             BUS_DMASYNC_POSTWRITE);
2195         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
2196         mfi_release_command(cm);
2197
2198         return (error);
2199 }
2200
2201 static int
2202 mfi_open(struct dev_open_args *ap)
2203 {
2204         cdev_t dev = ap->a_head.a_dev;
2205         struct mfi_softc *sc;
2206         int error;
2207
2208         sc = dev->si_drv1;
2209
2210         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2211         if (sc->mfi_detaching)
2212                 error = ENXIO;
2213         else {
2214                 sc->mfi_flags |= MFI_FLAGS_OPEN;
2215                 error = 0;
2216         }
2217         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2218
2219         return (error);
2220 }
2221
2222 static int
2223 mfi_close(struct dev_close_args *ap)
2224 {
2225         cdev_t dev = ap->a_head.a_dev;
2226         struct mfi_softc *sc;
2227         struct mfi_aen *mfi_aen_entry, *tmp;
2228
2229         sc = dev->si_drv1;
2230
2231         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2232         sc->mfi_flags &= ~MFI_FLAGS_OPEN;
2233
2234         TAILQ_FOREACH_MUTABLE(mfi_aen_entry, &sc->mfi_aen_pids, aen_link, tmp) {
2235                 if (mfi_aen_entry->p == curproc) {
2236                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
2237                             aen_link);
2238                         kfree(mfi_aen_entry, M_MFIBUF);
2239                 }
2240         }
2241         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2242         return (0);
2243 }
2244
2245 static int
2246 mfi_config_lock(struct mfi_softc *sc, uint32_t opcode)
2247 {
2248
2249         switch (opcode) {
2250         case MFI_DCMD_LD_DELETE:
2251         case MFI_DCMD_CFG_ADD:
2252         case MFI_DCMD_CFG_CLEAR:
2253                 lockmgr(&sc->mfi_config_lock, LK_EXCLUSIVE);
2254                 return (1);
2255         default:
2256                 return (0);
2257         }
2258 }
2259
2260 static void
2261 mfi_config_unlock(struct mfi_softc *sc, int locked)
2262 {
2263
2264         if (locked)
2265                 lockmgr(&sc->mfi_config_lock, LK_RELEASE);
2266 }
2267
2268 /* Perform pre-issue checks on commands from userland and possibly veto them. */
2269 static int
2270 mfi_check_command_pre(struct mfi_softc *sc, struct mfi_command *cm)
2271 {
2272         struct mfi_disk *ld, *ld2;
2273         int error;
2274         struct mfi_system_pd *syspd = NULL;
2275         uint16_t syspd_id;
2276         uint16_t *mbox;
2277
2278         KKASSERT(lockstatus(&sc->mfi_io_lock, curthread) != 0);
2279         error = 0;
2280         switch (cm->cm_frame->dcmd.opcode) {
2281         case MFI_DCMD_LD_DELETE:
2282                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2283                         if (ld->ld_id == cm->cm_frame->dcmd.mbox[0])
2284                                 break;
2285                 }
2286                 if (ld == NULL)
2287                         error = ENOENT;
2288                 else
2289                         error = mfi_disk_disable(ld);
2290                 break;
2291         case MFI_DCMD_CFG_CLEAR:
2292                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2293                         error = mfi_disk_disable(ld);
2294                         if (error)
2295                                 break;
2296                 }
2297                 if (error) {
2298                         TAILQ_FOREACH(ld2, &sc->mfi_ld_tqh, ld_link) {
2299                                 if (ld2 == ld)
2300                                         break;
2301                                 mfi_disk_enable(ld2);
2302                         }
2303                 }
2304                 break;
2305         case MFI_DCMD_PD_STATE_SET:
2306                 mbox = (uint16_t *)cm->cm_frame->dcmd.mbox;
2307                 syspd_id = mbox[0];
2308                 if (mbox[2] == MFI_PD_STATE_UNCONFIGURED_GOOD) {
2309                         if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
2310                                 TAILQ_FOREACH(syspd, &sc->mfi_syspd_tqh, pd_link) {
2311                                         if (syspd->pd_id == syspd_id)
2312                                                 break;
2313                                 }
2314                         }
2315                 } else {
2316                         break;
2317                 }
2318                 if(syspd)
2319                         error = mfi_syspd_disable(syspd);
2320                 break;
2321         default:
2322                 break;
2323         }
2324         return (error);
2325 }
2326
2327 /* Perform post-issue checks on commands from userland. */
2328 static void
2329 mfi_check_command_post(struct mfi_softc *sc, struct mfi_command *cm)
2330 {
2331         struct mfi_disk *ld, *ldn;
2332         struct mfi_system_pd *syspd = NULL;
2333         uint16_t syspd_id;
2334         uint16_t *mbox;
2335
2336         switch (cm->cm_frame->dcmd.opcode) {
2337         case MFI_DCMD_LD_DELETE:
2338                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2339                         if (ld->ld_id == cm->cm_frame->dcmd.mbox[0])
2340                                 break;
2341                 }
2342                 KASSERT(ld != NULL, ("volume dissappeared"));
2343                 if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) {
2344                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2345                         get_mplock();
2346                         device_delete_child(sc->mfi_dev, ld->ld_dev);
2347                         rel_mplock();
2348                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2349                 } else
2350                         mfi_disk_enable(ld);
2351                 break;
2352         case MFI_DCMD_CFG_CLEAR:
2353                 if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) {
2354                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2355                         get_mplock();
2356                         TAILQ_FOREACH_MUTABLE(ld, &sc->mfi_ld_tqh, ld_link, ldn) {
2357                                 device_delete_child(sc->mfi_dev, ld->ld_dev);
2358                         }
2359                         rel_mplock();
2360                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2361                 } else {
2362                         TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link)
2363                                 mfi_disk_enable(ld);
2364                 }
2365                 break;
2366         case MFI_DCMD_CFG_ADD:
2367                 mfi_ldprobe(sc);
2368                 break;
2369         case MFI_DCMD_CFG_FOREIGN_IMPORT:
2370                 mfi_ldprobe(sc);
2371                 break;
2372         case MFI_DCMD_PD_STATE_SET:
2373                 mbox = (uint16_t *)cm->cm_frame->dcmd.mbox;
2374                 syspd_id = mbox[0];
2375                 if (mbox[2] == MFI_PD_STATE_UNCONFIGURED_GOOD) {
2376                         if (!TAILQ_EMPTY(&sc->mfi_syspd_tqh)) {
2377                                 TAILQ_FOREACH(syspd,&sc->mfi_syspd_tqh,pd_link) {
2378                                         if (syspd->pd_id == syspd_id)
2379                                                 break;
2380                                 }
2381                         }
2382                 } else {
2383                         break;
2384                 }
2385                 /* If the transition fails then enable the syspd again */
2386                 if(syspd && cm->cm_frame->header.cmd_status != MFI_STAT_OK)
2387                         mfi_syspd_enable(syspd);
2388                 break;
2389         }
2390 }
2391
2392 static int
2393 mfi_user_command(struct mfi_softc *sc, struct mfi_ioc_passthru *ioc)
2394 {
2395         struct mfi_command *cm;
2396         struct mfi_dcmd_frame *dcmd;
2397         void *ioc_buf = NULL;
2398         uint32_t context;
2399         int error = 0, locked;
2400
2401
2402         if (ioc->buf_size > 0) {
2403                 ioc_buf = kmalloc(ioc->buf_size, M_MFIBUF, M_WAITOK);
2404                 error = copyin(ioc->buf, ioc_buf, ioc->buf_size);
2405                 if (error) {
2406                         device_printf(sc->mfi_dev, "failed to copyin\n");
2407                         kfree(ioc_buf, M_MFIBUF);
2408                         return (error);
2409                 }
2410         }
2411
2412         locked = mfi_config_lock(sc, ioc->ioc_frame.opcode);
2413
2414         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2415         while ((cm = mfi_dequeue_free(sc)) == NULL)
2416                 lksleep(mfi_user_command, &sc->mfi_io_lock, 0, "mfiioc", hz);
2417
2418         /* Save context for later */
2419         context = cm->cm_frame->header.context;
2420
2421         dcmd = &cm->cm_frame->dcmd;
2422         bcopy(&ioc->ioc_frame, dcmd, sizeof(struct mfi_dcmd_frame));
2423
2424         cm->cm_sg = &dcmd->sgl;
2425         cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
2426         cm->cm_data = ioc_buf;
2427         cm->cm_len = ioc->buf_size;
2428
2429         /* restore context */
2430         cm->cm_frame->header.context = context;
2431
2432         /* Cheat since we don't know if we're writing or reading */
2433         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_DATAOUT;
2434
2435         error = mfi_check_command_pre(sc, cm);
2436         if (error)
2437                 goto out;
2438
2439         error = mfi_wait_command(sc, cm);
2440         if (error) {
2441                 device_printf(sc->mfi_dev, "ioctl failed %d\n", error);
2442                 goto out;
2443         }
2444         bcopy(dcmd, &ioc->ioc_frame, sizeof(struct mfi_dcmd_frame));
2445         mfi_check_command_post(sc, cm);
2446 out:
2447         mfi_release_command(cm);
2448         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2449         mfi_config_unlock(sc, locked);
2450         if (ioc->buf_size > 0)
2451                 error = copyout(ioc_buf, ioc->buf, ioc->buf_size);
2452         if (ioc_buf)
2453                 kfree(ioc_buf, M_MFIBUF);
2454         return (error);
2455 }
2456
2457 #ifdef __x86_64__
2458 #define PTRIN(p)                ((void *)(uintptr_t)(p))
2459 #else
2460 #define PTRIN(p)                (p)
2461 #endif
2462
2463 static int
2464 mfi_check_for_sscd(struct mfi_softc *sc, struct mfi_command *cm)
2465 {
2466         struct mfi_config_data *conf_data = cm->cm_data;
2467         struct mfi_command *ld_cm = NULL;
2468         struct mfi_ld_info *ld_info = NULL;
2469         int error = 0;
2470
2471         if ((cm->cm_frame->dcmd.opcode == MFI_DCMD_CFG_ADD) &&
2472             (conf_data->ld[0].params.isSSCD == 1)) {
2473                 error = 1;
2474         } else if (cm->cm_frame->dcmd.opcode == MFI_DCMD_LD_DELETE) {
2475                 error = mfi_dcmd_command(sc, &ld_cm, MFI_DCMD_LD_GET_INFO,
2476                     (void **)&ld_info, sizeof(*ld_info));
2477                 if (error) {
2478                         device_printf(sc->mfi_dev,"Failed to allocate "
2479                             "MFI_DCMD_LD_GET_INFO %d", error);
2480                         if (ld_info)
2481                                 kfree(ld_info, M_MFIBUF);
2482                         return 0;
2483                 }
2484                 ld_cm->cm_flags = MFI_CMD_DATAIN;
2485                 ld_cm->cm_frame->dcmd.mbox[0]= cm->cm_frame->dcmd.mbox[0];
2486                 ld_cm->cm_frame->header.target_id = cm->cm_frame->dcmd.mbox[0];
2487                 if (mfi_wait_command(sc, ld_cm) != 0) {
2488                         device_printf(sc->mfi_dev, "failed to get log drv\n");
2489                         mfi_release_command(ld_cm);
2490                         kfree(ld_info, M_MFIBUF);
2491                         return 0;
2492                 }
2493
2494                 if (ld_cm->cm_frame->header.cmd_status != MFI_STAT_OK) {
2495                         kfree(ld_info, M_MFIBUF);
2496                         mfi_release_command(ld_cm);
2497                         return 0;
2498                 } else {
2499                         ld_info = (struct mfi_ld_info *)ld_cm->cm_private;
2500                 }
2501
2502                 if (ld_info->ld_config.params.isSSCD == 1)
2503                         error = 1;
2504
2505                 mfi_release_command(ld_cm);
2506                 kfree(ld_info, M_MFIBUF);
2507         }
2508         return error;
2509 }
2510
2511 static int
2512 mfi_ioctl(struct dev_ioctl_args *ap)
2513 {
2514         cdev_t dev = ap->a_head.a_dev;
2515         u_long cmd = ap->a_cmd;
2516         int flag = ap->a_fflag;
2517         caddr_t arg = ap->a_data;
2518         struct mfi_softc *sc;
2519         union mfi_statrequest *ms;
2520         struct mfi_ioc_packet *ioc;
2521 #ifdef __x86_64__
2522         struct mfi_ioc_packet32 *ioc32;
2523 #endif
2524         struct mfi_ioc_aen *aen;
2525         struct mfi_command *cm = NULL;
2526         uint32_t context;
2527         union mfi_sense_ptr sense_ptr;
2528         uint8_t *data = NULL, *temp, *addr, skip_pre_post = 0;
2529         size_t len;
2530         int i;
2531         struct mfi_ioc_passthru *iop = (struct mfi_ioc_passthru *)arg;
2532 #ifdef __x86_64__
2533         struct mfi_ioc_passthru32 *iop32 = (struct mfi_ioc_passthru32 *)arg;
2534         struct mfi_ioc_passthru iop_swab;
2535 #endif
2536         int error, locked;
2537
2538         sc = dev->si_drv1;
2539         error = 0;
2540
2541         switch (cmd) {
2542         case MFIIO_STATS:
2543                 ms = (union mfi_statrequest *)arg;
2544                 switch (ms->ms_item) {
2545                 case MFIQ_FREE:
2546                 case MFIQ_BIO:
2547                 case MFIQ_READY:
2548                 case MFIQ_BUSY:
2549                         bcopy(&sc->mfi_qstat[ms->ms_item], &ms->ms_qstat,
2550                             sizeof(struct mfi_qstat));
2551                         break;
2552                 default:
2553                         error = ENOIOCTL;
2554                         break;
2555                 }
2556                 break;
2557         case MFIIO_QUERY_DISK:
2558         {
2559                 struct mfi_query_disk *qd;
2560                 struct mfi_disk *ld;
2561
2562                 qd = (struct mfi_query_disk *)arg;
2563                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2564                 TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
2565                         if (ld->ld_id == qd->array_id)
2566                                 break;
2567                 }
2568                 if (ld == NULL) {
2569                         qd->present = 0;
2570                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2571                         return (0);
2572                 }
2573                 qd->present = 1;
2574                 if (ld->ld_flags & MFI_DISK_FLAGS_OPEN)
2575                         qd->open = 1;
2576                 bzero(qd->devname, SPECNAMELEN + 1);
2577                 ksnprintf(qd->devname, SPECNAMELEN, "mfid%d", ld->ld_unit);
2578                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2579                 break;
2580         }
2581         case MFI_CMD:
2582 #ifdef __x86_64__
2583         case MFI_CMD32:
2584 #endif
2585                 {
2586                 devclass_t devclass;
2587                 ioc = (struct mfi_ioc_packet *)arg;
2588                 int adapter;
2589
2590                 adapter = ioc->mfi_adapter_no;
2591                 if (device_get_unit(sc->mfi_dev) == 0 && adapter != 0) {
2592                         devclass = devclass_find("mfi");
2593                         sc = devclass_get_softc(devclass, adapter);
2594                 }
2595                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2596                 if ((cm = mfi_dequeue_free(sc)) == NULL) {
2597                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2598                         return (EBUSY);
2599                 }
2600                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2601                 locked = 0;
2602
2603                 /*
2604                  * save off original context since copying from user
2605                  * will clobber some data
2606                  */
2607                 context = cm->cm_frame->header.context;
2608
2609                 bcopy(ioc->mfi_frame.raw, cm->cm_frame,
2610                     2 * MFI_DCMD_FRAME_SIZE);  /* this isn't quite right */
2611                 cm->cm_total_frame_size = (sizeof(union mfi_sgl)
2612                     * ioc->mfi_sge_count) + ioc->mfi_sgl_off;
2613                 cm->cm_frame->header.scsi_status = 0;
2614                 cm->cm_frame->header.pad0 = 0;
2615                 if (ioc->mfi_sge_count) {
2616                         cm->cm_sg =
2617                             (union mfi_sgl *)&cm->cm_frame->bytes[ioc->mfi_sgl_off];
2618                 }
2619                 cm->cm_flags = 0;
2620                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAIN)
2621                         cm->cm_flags |= MFI_CMD_DATAIN;
2622                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAOUT)
2623                         cm->cm_flags |= MFI_CMD_DATAOUT;
2624                 /* Legacy app shim */
2625                 if (cm->cm_flags == 0)
2626                         cm->cm_flags |= MFI_CMD_DATAIN | MFI_CMD_DATAOUT;
2627                 cm->cm_len = cm->cm_frame->header.data_len;
2628                 if (cm->cm_frame->header.cmd == MFI_CMD_STP) {
2629 #ifdef __x86_64__
2630                         if (cmd == MFI_CMD) {
2631 #endif
2632                                 /* Native */
2633                                 cm->cm_stp_len = ioc->mfi_sgl[0].iov_len;
2634 #ifdef __x86_64__
2635                         } else {
2636                                 /* 32bit on 64bit */
2637                                 ioc32 = (struct mfi_ioc_packet32 *)ioc;
2638                                 cm->cm_stp_len = ioc32->mfi_sgl[0].iov_len;
2639                         }
2640 #endif
2641                         cm->cm_len += cm->cm_stp_len;
2642                 }
2643                 if (cm->cm_len &&
2644                     (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) {
2645                         cm->cm_data = data = kmalloc(cm->cm_len, M_MFIBUF,
2646                             M_WAITOK | M_ZERO);
2647                 } else {
2648                         cm->cm_data = 0;
2649                 }
2650
2651                 /* restore header context */
2652                 cm->cm_frame->header.context = context;
2653
2654                 temp = data;
2655                 if ((cm->cm_flags & MFI_CMD_DATAOUT) ||
2656                     (cm->cm_frame->header.cmd == MFI_CMD_STP)) {
2657                         for (i = 0; i < ioc->mfi_sge_count; i++) {
2658 #ifdef __x86_64__
2659                                 if (cmd == MFI_CMD) {
2660 #endif
2661                                         /* Native */
2662                                         addr = ioc->mfi_sgl[i].iov_base;
2663                                         len = ioc->mfi_sgl[i].iov_len;
2664 #ifdef __x86_64__
2665                                 } else {
2666                                         /* 32bit on 64bit */
2667                                         ioc32 = (struct mfi_ioc_packet32 *)ioc;
2668                                         addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
2669                                         len = ioc32->mfi_sgl[i].iov_len;
2670                                 }
2671 #endif
2672                                 error = copyin(addr, temp, len);
2673                                 if (error != 0) {
2674                                         device_printf(sc->mfi_dev,
2675                                             "Copy in failed\n");
2676                                         goto out;
2677                                 }
2678                                 temp = &temp[len];
2679                         }
2680                 }
2681
2682                 if (cm->cm_frame->header.cmd == MFI_CMD_DCMD)
2683                         locked = mfi_config_lock(sc, cm->cm_frame->dcmd.opcode);
2684
2685                 if (cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) {
2686 #if defined(__x86_64__)
2687                         cm->cm_frame->pass.sense_addr_lo =
2688                             (cm->cm_sense_busaddr & 0xFFFFFFFF);
2689                         cm->cm_frame->pass.sense_addr_hi =
2690                             (cm->cm_sense_busaddr& 0xFFFFFFFF00000000) >> 32;
2691 #else
2692                         cm->cm_frame->pass.sense_addr_lo = cm->cm_sense_busaddr;
2693                         cm->cm_frame->pass.sense_addr_hi = 0;
2694 #endif
2695                 }
2696
2697                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2698                 skip_pre_post = mfi_check_for_sscd(sc, cm);
2699                 if (!skip_pre_post) {
2700                         error = mfi_check_command_pre(sc, cm);
2701                         if (error) {
2702                                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2703                                 goto out;
2704                         }
2705                 }
2706
2707                 if ((error = mfi_wait_command(sc, cm)) != 0) {
2708                         device_printf(sc->mfi_dev,
2709                             "Controller polled failed\n");
2710                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2711                         goto out;
2712                 }
2713
2714                 if (!skip_pre_post)
2715                         mfi_check_command_post(sc, cm);
2716                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2717
2718                 temp = data;
2719                 if ((cm->cm_flags & MFI_CMD_DATAIN) ||
2720                     (cm->cm_frame->header.cmd == MFI_CMD_STP)) {
2721                         for (i = 0; i < ioc->mfi_sge_count; i++) {
2722 #ifdef __x86_64__
2723                                 if (cmd == MFI_CMD) {
2724 #endif
2725                                         /* Native */
2726                                         addr = ioc->mfi_sgl[i].iov_base;
2727                                         len = ioc->mfi_sgl[i].iov_len;
2728 #ifdef __x86_64__
2729                                 } else {
2730                                         /* 32bit on 64bit */
2731                                         ioc32 = (struct mfi_ioc_packet32 *)ioc;
2732                                         addr = PTRIN(ioc32->mfi_sgl[i].iov_base);
2733                                         len = ioc32->mfi_sgl[i].iov_len;
2734                                 }
2735 #endif
2736                                 error = copyout(temp, addr, len);
2737                                 if (error != 0) {
2738                                         device_printf(sc->mfi_dev,
2739                                             "Copy out failed\n");
2740                                         goto out;
2741                                 }
2742                                 temp = &temp[len];
2743                         }
2744                 }
2745
2746                 if (ioc->mfi_sense_len) {
2747                         /* get user-space sense ptr then copy out sense */
2748                         bcopy(&ioc->mfi_frame.raw[ioc->mfi_sense_off],
2749                             &sense_ptr.sense_ptr_data[0],
2750                             sizeof(sense_ptr.sense_ptr_data));
2751 #ifdef __x86_64__
2752                         if (cmd != MFI_CMD) {
2753                                 /*
2754                                  * not 64bit native so zero out any address
2755                                  * over 32bit */
2756                                 sense_ptr.addr.high = 0;
2757                         }
2758 #endif
2759                         error = copyout(cm->cm_sense, sense_ptr.user_space,
2760                             ioc->mfi_sense_len);
2761                         if (error != 0) {
2762                                 device_printf(sc->mfi_dev,
2763                                     "Copy out failed\n");
2764                                 goto out;
2765                         }
2766                 }
2767
2768                 ioc->mfi_frame.hdr.cmd_status = cm->cm_frame->header.cmd_status;
2769 out:
2770                 mfi_config_unlock(sc, locked);
2771                 if (data)
2772                         kfree(data, M_MFIBUF);
2773                 if (cm) {
2774                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2775                         mfi_release_command(cm);
2776                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2777                 }
2778
2779                 break;
2780                 }
2781         case MFI_SET_AEN:
2782                 aen = (struct mfi_ioc_aen *)arg;
2783                 error = mfi_aen_register(sc, aen->aen_seq_num,
2784                     aen->aen_class_locale);
2785
2786                 break;
2787         case MFI_LINUX_CMD_2: /* Firmware Linux ioctl shim */
2788                 {
2789                         devclass_t devclass;
2790                         struct mfi_linux_ioc_packet l_ioc;
2791                         int adapter;
2792
2793                         devclass = devclass_find("mfi");
2794                         if (devclass == NULL)
2795                                 return (ENOENT);
2796
2797                         error = copyin(arg, &l_ioc, sizeof(l_ioc));
2798                         if (error)
2799                                 return (error);
2800                         adapter = l_ioc.lioc_adapter_no;
2801                         sc = devclass_get_softc(devclass, adapter);
2802                         if (sc == NULL)
2803                                 return (ENOENT);
2804                         return (mfi_linux_ioctl_int(sc->mfi_cdev,
2805                             cmd, arg, flag));
2806                         break;
2807                 }
2808         case MFI_LINUX_SET_AEN_2: /* AEN Linux ioctl shim */
2809                 {
2810                         devclass_t devclass;
2811                         struct mfi_linux_ioc_aen l_aen;
2812                         int adapter;
2813
2814                         devclass = devclass_find("mfi");
2815                         if (devclass == NULL)
2816                                 return (ENOENT);
2817
2818                         error = copyin(arg, &l_aen, sizeof(l_aen));
2819                         if (error)
2820                                 return (error);
2821                         adapter = l_aen.laen_adapter_no;
2822                         sc = devclass_get_softc(devclass, adapter);
2823                         if (sc == NULL)
2824                                 return (ENOENT);
2825                         return (mfi_linux_ioctl_int(sc->mfi_cdev,
2826                             cmd, arg, flag));
2827                         break;
2828                 }
2829 #ifdef __x86_64__
2830         case MFIIO_PASSTHRU32:
2831                 iop_swab.ioc_frame      = iop32->ioc_frame;
2832                 iop_swab.buf_size       = iop32->buf_size;
2833                 iop_swab.buf            = PTRIN(iop32->buf);
2834                 iop                     = &iop_swab;
2835                 /* FALLTHROUGH */
2836 #endif
2837         case MFIIO_PASSTHRU:
2838                 error = mfi_user_command(sc, iop);
2839 #ifdef __x86_64__
2840                 if (cmd == MFIIO_PASSTHRU32)
2841                         iop32->ioc_frame = iop_swab.ioc_frame;
2842 #endif
2843                 break;
2844         default:
2845                 device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd);
2846                 error = ENOENT;
2847                 break;
2848         }
2849
2850         return (error);
2851 }
2852
2853 static int
2854 mfi_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t arg, int flag)
2855 {
2856         struct mfi_softc *sc;
2857         struct mfi_linux_ioc_packet l_ioc;
2858         struct mfi_linux_ioc_aen l_aen;
2859         struct mfi_command *cm = NULL;
2860         struct mfi_aen *mfi_aen_entry;
2861         union mfi_sense_ptr sense_ptr;
2862         uint32_t context;
2863         uint8_t *data = NULL, *temp;
2864         int i;
2865         int error, locked;
2866
2867         sc = dev->si_drv1;
2868         error = 0;
2869         switch (cmd) {
2870         case MFI_LINUX_CMD_2: /* Firmware Linux ioctl shim */
2871                 error = copyin(arg, &l_ioc, sizeof(l_ioc));
2872                 if (error != 0)
2873                         return (error);
2874
2875                 if (l_ioc.lioc_sge_count > MAX_LINUX_IOCTL_SGE) {
2876                         return (EINVAL);
2877                 }
2878
2879                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2880                 if ((cm = mfi_dequeue_free(sc)) == NULL) {
2881                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2882                         return (EBUSY);
2883                 }
2884                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2885                 locked = 0;
2886
2887                 /*
2888                  * save off original context since copying from user
2889                  * will clobber some data
2890                  */
2891                 context = cm->cm_frame->header.context;
2892
2893                 bcopy(l_ioc.lioc_frame.raw, cm->cm_frame,
2894                       2 * MFI_DCMD_FRAME_SIZE); /* this isn't quite right */
2895                 cm->cm_total_frame_size = (sizeof(union mfi_sgl)
2896                       * l_ioc.lioc_sge_count) + l_ioc.lioc_sgl_off;
2897                 cm->cm_frame->header.scsi_status = 0;
2898                 cm->cm_frame->header.pad0 = 0;
2899                 if (l_ioc.lioc_sge_count)
2900                         cm->cm_sg =
2901                             (union mfi_sgl *)&cm->cm_frame->bytes[l_ioc.lioc_sgl_off];
2902                 cm->cm_flags = 0;
2903                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAIN)
2904                         cm->cm_flags |= MFI_CMD_DATAIN;
2905                 if (cm->cm_frame->header.flags & MFI_FRAME_DATAOUT)
2906                         cm->cm_flags |= MFI_CMD_DATAOUT;
2907                 cm->cm_len = cm->cm_frame->header.data_len;
2908                 if (cm->cm_len &&
2909                       (cm->cm_flags & (MFI_CMD_DATAIN | MFI_CMD_DATAOUT))) {
2910                         cm->cm_data = data = kmalloc(cm->cm_len, M_MFIBUF,
2911                             M_WAITOK | M_ZERO);
2912                 } else {
2913                         cm->cm_data = 0;
2914                 }
2915
2916                 /* restore header context */
2917                 cm->cm_frame->header.context = context;
2918
2919                 temp = data;
2920                 if (cm->cm_flags & MFI_CMD_DATAOUT) {
2921                         for (i = 0; i < l_ioc.lioc_sge_count; i++) {
2922                                 error = copyin(PTRIN(l_ioc.lioc_sgl[i].iov_base),
2923                                        temp,
2924                                        l_ioc.lioc_sgl[i].iov_len);
2925                                 if (error != 0) {
2926                                         device_printf(sc->mfi_dev,
2927                                             "Copy in failed\n");
2928                                         goto out;
2929                                 }
2930                                 temp = &temp[l_ioc.lioc_sgl[i].iov_len];
2931                         }
2932                 }
2933
2934                 if (cm->cm_frame->header.cmd == MFI_CMD_DCMD)
2935                         locked = mfi_config_lock(sc, cm->cm_frame->dcmd.opcode);
2936
2937                 if (cm->cm_frame->header.cmd == MFI_CMD_PD_SCSI_IO) {
2938 #if defined(__x86_64__)
2939                         cm->cm_frame->pass.sense_addr_lo =
2940                             (cm->cm_sense_busaddr & 0xFFFFFFFF);
2941                         cm->cm_frame->pass.sense_addr_hi =
2942                             (cm->cm_sense_busaddr & 0xFFFFFFFF00000000) >> 32;
2943 #else
2944                         cm->cm_frame->pass.sense_addr_lo = cm->cm_sense_busaddr;
2945                         cm->cm_frame->pass.sense_addr_hi = 0;
2946 #endif
2947                 }
2948
2949                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
2950                 error = mfi_check_command_pre(sc, cm);
2951                 if (error) {
2952                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2953                         goto out;
2954                 }
2955
2956                 if ((error = mfi_wait_command(sc, cm)) != 0) {
2957                         device_printf(sc->mfi_dev,
2958                             "Controller polled failed\n");
2959                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2960                         goto out;
2961                 }
2962
2963                 mfi_check_command_post(sc, cm);
2964                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
2965
2966                 temp = data;
2967                 if (cm->cm_flags & MFI_CMD_DATAIN) {
2968                         for (i = 0; i < l_ioc.lioc_sge_count; i++) {
2969                                 error = copyout(temp,
2970                                         PTRIN(l_ioc.lioc_sgl[i].iov_base),
2971                                         l_ioc.lioc_sgl[i].iov_len);
2972                                 if (error != 0) {
2973                                         device_printf(sc->mfi_dev,
2974                                             "Copy out failed\n");
2975                                         goto out;
2976                                 }
2977                                 temp = &temp[l_ioc.lioc_sgl[i].iov_len];
2978                         }
2979                 }
2980
2981                 if (l_ioc.lioc_sense_len) {
2982                         /* get user-space sense ptr then copy out sense */
2983                         bcopy(&((struct mfi_linux_ioc_packet*)arg)
2984                             ->lioc_frame.raw[l_ioc.lioc_sense_off],
2985                             &sense_ptr.sense_ptr_data[0],
2986                             sizeof(sense_ptr.sense_ptr_data));
2987 #ifdef __x86_64__
2988                         /*
2989                          * only 32bit Linux support so zero out any
2990                          * address over 32bit
2991                          */
2992                         sense_ptr.addr.high = 0;
2993 #endif
2994                         error = copyout(cm->cm_sense, sense_ptr.user_space,
2995                             l_ioc.lioc_sense_len);
2996                         if (error != 0) {
2997                                 device_printf(sc->mfi_dev,
2998                                     "Copy out failed\n");
2999                                 goto out;
3000                         }
3001                 }
3002
3003                 error = copyout(&cm->cm_frame->header.cmd_status,
3004                         &((struct mfi_linux_ioc_packet*)arg)
3005                         ->lioc_frame.hdr.cmd_status,
3006                         1);
3007                 if (error != 0) {
3008                         device_printf(sc->mfi_dev,
3009                                       "Copy out failed\n");
3010                         goto out;
3011                 }
3012
3013 out:
3014                 mfi_config_unlock(sc, locked);
3015                 if (data)
3016                         kfree(data, M_MFIBUF);
3017                 if (cm) {
3018                         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3019                         mfi_release_command(cm);
3020                         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3021                 }
3022
3023                 return (error);
3024         case MFI_LINUX_SET_AEN_2: /* AEN Linux ioctl shim */
3025                 error = copyin(arg, &l_aen, sizeof(l_aen));
3026                 if (error != 0)
3027                         return (error);
3028                 kprintf("AEN IMPLEMENTED for pid %d\n", curproc->p_pid);
3029                 mfi_aen_entry = kmalloc(sizeof(struct mfi_aen), M_MFIBUF,
3030                     M_WAITOK);
3031                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3032                 if (mfi_aen_entry != NULL) {
3033                         mfi_aen_entry->p = curproc;
3034                         TAILQ_INSERT_TAIL(&sc->mfi_aen_pids, mfi_aen_entry,
3035                             aen_link);
3036                 }
3037                 error = mfi_aen_register(sc, l_aen.laen_seq_num,
3038                     l_aen.laen_class_locale);
3039
3040                 if (error != 0) {
3041                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
3042                             aen_link);
3043                         kfree(mfi_aen_entry, M_MFIBUF);
3044                 }
3045                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3046
3047                 return (error);
3048         default:
3049                 device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd);
3050                 error = ENOENT;
3051                 break;
3052         }
3053
3054         return (error);
3055 }
3056
3057 static int
3058 mfi_kqfilter(struct dev_kqfilter_args *ap)
3059 {
3060         cdev_t dev = ap->a_head.a_dev;
3061         struct knote *kn = ap->a_kn;
3062         struct mfi_softc *sc;
3063         struct klist *klist;
3064
3065         ap->a_result = 0;
3066         sc = dev->si_drv1;
3067
3068         switch (kn->kn_filter) {
3069         case EVFILT_READ:
3070                 kn->kn_fop = &mfi_read_filterops;
3071                 kn->kn_hook = (caddr_t)sc;
3072                 break;
3073         case EVFILT_WRITE:
3074                 kn->kn_fop = &mfi_write_filterops;
3075                 kn->kn_hook = (caddr_t)sc;
3076                 break;
3077         default:
3078                 ap->a_result = EOPNOTSUPP;
3079                 return (0);
3080         }
3081
3082         klist = &sc->mfi_kq.ki_note;
3083         knote_insert(klist, kn);
3084
3085         return(0);
3086 }
3087
3088 static void
3089 mfi_filter_detach(struct knote *kn)
3090 {
3091         struct mfi_softc *sc = (struct mfi_softc *)kn->kn_hook;
3092         struct klist *klist = &sc->mfi_kq.ki_note;
3093
3094         knote_remove(klist, kn);
3095 }
3096
3097 static int
3098 mfi_filter_read(struct knote *kn, long hint)
3099 {
3100         struct mfi_softc *sc = (struct mfi_softc *)kn->kn_hook;
3101         int ready = 0;
3102
3103         if (sc->mfi_aen_triggered != 0) {
3104                 ready = 1;
3105                 sc->mfi_aen_triggered = 0;
3106         }
3107         if (sc->mfi_aen_triggered == 0 && sc->mfi_aen_cm == NULL)
3108                 kn->kn_flags |= EV_ERROR;
3109
3110         if (ready == 0)
3111                 sc->mfi_poll_waiting = 1;
3112
3113         return (ready);
3114 }
3115
3116 static int
3117 mfi_filter_write(struct knote *kn, long hint)
3118 {
3119         return (0);
3120 }
3121
3122 static void
3123 mfi_dump_all(void)
3124 {
3125         struct mfi_softc *sc;
3126         struct mfi_command *cm;
3127         devclass_t dc;
3128         time_t deadline;
3129         int timedout;
3130         int i;
3131
3132         dc = devclass_find("mfi");
3133         if (dc == NULL) {
3134                 kprintf("No mfi dev class\n");
3135                 return;
3136         }
3137
3138         for (i = 0; ; i++) {
3139                 sc = devclass_get_softc(dc, i);
3140                 if (sc == NULL)
3141                         break;
3142                 device_printf(sc->mfi_dev, "Dumping\n\n");
3143                 timedout = 0;
3144                 deadline = time_second - MFI_CMD_TIMEOUT;
3145                 lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3146                 TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {
3147                         if (cm->cm_timestamp < deadline) {
3148                                 device_printf(sc->mfi_dev,
3149                                     "COMMAND %p TIMEOUT AFTER %d SECONDS\n", cm,
3150                                     (int)(time_second - cm->cm_timestamp));
3151                                 MFI_PRINT_CMD(cm);
3152                                 timedout++;
3153                         }
3154                 }
3155
3156 #if 0
3157                 if (timedout)
3158                         MFI_DUMP_CMDS(SC);
3159 #endif
3160
3161                 lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3162         }
3163
3164         return;
3165 }
3166
3167 static void
3168 mfi_timeout(void *data)
3169 {
3170         struct mfi_softc *sc = (struct mfi_softc *)data;
3171         struct mfi_command *cm;
3172         time_t deadline;
3173         int timedout = 0;
3174
3175         deadline = time_second - MFI_CMD_TIMEOUT;
3176         lockmgr(&sc->mfi_io_lock, LK_EXCLUSIVE);
3177         TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {
3178                 if (sc->mfi_aen_cm == cm)
3179                         continue;
3180                 if ((sc->mfi_aen_cm != cm) && (cm->cm_timestamp < deadline)) {
3181                         device_printf(sc->mfi_dev,
3182                             "COMMAND %p TIMEOUT AFTER %d SECONDS\n", cm,
3183                             (int)(time_second - cm->cm_timestamp));
3184                         MFI_PRINT_CMD(cm);
3185                         MFI_VALIDATE_CMD(sc, cm);
3186                         timedout++;
3187                 }
3188         }
3189
3190 #if 0
3191         if (timedout)
3192                 MFI_DUMP_CMDS(SC);
3193 #endif
3194
3195         lockmgr(&sc->mfi_io_lock, LK_RELEASE);
3196
3197         callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,
3198             mfi_timeout, sc);
3199
3200         if (0)
3201                 mfi_dump_all();
3202         return;
3203 }