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