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