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