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