Deleted Added
sdiff udiff text old ( 233711 ) new ( 235014 )
full compact
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

--- 37 unchanged lines hidden (view full) ---

46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 */
52
53#include <sys/cdefs.h>
54__FBSDID("$FreeBSD: head/sys/dev/mfi/mfi.c 235014 2012-05-04 16:00:39Z ambrisko $");
55
56#include "opt_compat.h"
57#include "opt_mfi.h"
58
59#include <sys/param.h>
60#include <sys/systm.h>
61#include <sys/sysctl.h>
62#include <sys/malloc.h>

--- 22 unchanged lines hidden (view full) ---

85#include <sys/priority.h>
86
87static int mfi_alloc_commands(struct mfi_softc *);
88static int mfi_comms_init(struct mfi_softc *);
89static int mfi_get_controller_info(struct mfi_softc *);
90static int mfi_get_log_state(struct mfi_softc *,
91 struct mfi_evt_log_state **);
92static int mfi_parse_entries(struct mfi_softc *, int, int);
93static void mfi_data_cb(void *, bus_dma_segment_t *, int, int);
94static void mfi_startup(void *arg);
95static void mfi_intr(void *arg);
96static void mfi_ldprobe(struct mfi_softc *sc);
97static void mfi_syspdprobe(struct mfi_softc *sc);
98static void mfi_handle_evt(void *context, int pending);
99static int mfi_aen_register(struct mfi_softc *sc, int seq, int locale);
100static void mfi_aen_complete(struct mfi_command *);

--- 269 unchanged lines hidden (view full) ---

370 MEGASAS_VERSION);
371
372 mtx_init(&sc->mfi_io_lock, "MFI I/O lock", NULL, MTX_DEF);
373 sx_init(&sc->mfi_config_lock, "MFI config");
374 TAILQ_INIT(&sc->mfi_ld_tqh);
375 TAILQ_INIT(&sc->mfi_syspd_tqh);
376 TAILQ_INIT(&sc->mfi_evt_queue);
377 TASK_INIT(&sc->mfi_evt_task, 0, mfi_handle_evt, sc);
378 TASK_INIT(&sc->mfi_map_sync_task, 0, mfi_handle_map_sync, sc);
379 TAILQ_INIT(&sc->mfi_aen_pids);
380 TAILQ_INIT(&sc->mfi_cam_ccbq);
381
382 mfi_initq_free(sc);
383 mfi_initq_ready(sc);
384 mfi_initq_busy(sc);
385 mfi_initq_bio(sc);
386

--- 303 unchanged lines hidden (view full) ---

690 return error;
691 if (bus_setup_intr(sc->mfi_dev, sc->mfi_irq,
692 INTR_MPSAFE|INTR_TYPE_BIO, NULL, mfi_intr_tbolt, sc,
693 &sc->mfi_intr)) {
694 device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
695 return (EINVAL);
696 }
697 sc->mfi_enable_intr(sc);
698 } else {
699 if ((error = mfi_comms_init(sc)) != 0)
700 return (error);
701
702 if (bus_setup_intr(sc->mfi_dev, sc->mfi_irq,
703 INTR_MPSAFE|INTR_TYPE_BIO, NULL, mfi_intr, sc, &sc->mfi_intr)) {
704 device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
705 return (EINVAL);

--- 49 unchanged lines hidden (view full) ---

755 device_add_child(sc->mfi_dev, "mfip", -1);
756 bus_generic_attach(sc->mfi_dev);
757
758 /* Start the timeout watchdog */
759 callout_init(&sc->mfi_watchdog_callout, CALLOUT_MPSAFE);
760 callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,
761 mfi_timeout, sc);
762
763 if (sc->mfi_flags & MFI_FLAGS_TBOLT) {
764 mfi_tbolt_sync_map_info(sc);
765 }
766
767 return (0);
768}
769
770static int
771mfi_alloc_commands(struct mfi_softc *sc)
772{
773 struct mfi_command *cm;
774 int i, ncmds;

--- 67 unchanged lines hidden (view full) ---

842 cm->cm_data = NULL;
843 cm->cm_sg = 0;
844 cm->cm_total_frame_size = 0;
845 cm->retry_for_fw_reset = 0;
846
847 mfi_enqueue_free(cm);
848}
849
850int
851mfi_dcmd_command(struct mfi_softc *sc, struct mfi_command **cmp,
852 uint32_t opcode, void **bufp, size_t bufsize)
853{
854 struct mfi_command *cm;
855 struct mfi_dcmd_frame *dcmd;
856 void *buf = NULL;
857 uint32_t context = 0;
858

--- 424 unchanged lines hidden (view full) ---

1283 if (error) {
1284 mtx_unlock(&sc->mfi_io_lock);
1285 return (error);
1286 }
1287
1288 if (sc->mfi_aen_cm != NULL)
1289 mfi_abort(sc, sc->mfi_aen_cm);
1290
1291 if (sc->mfi_map_sync_cm != NULL)
1292 mfi_abort(sc, sc->mfi_map_sync_cm);
1293
1294 dcmd = &cm->cm_frame->dcmd;
1295 dcmd->header.flags = MFI_FRAME_DIR_NONE;
1296 cm->cm_flags = MFI_CMD_POLLED;
1297 cm->cm_data = NULL;
1298
1299 if ((error = mfi_mapcmd(sc, cm)) != 0) {
1300 device_printf(sc->mfi_dev, "Failed to shutdown controller\n");

--- 360 unchanged lines hidden (view full) ---

1661 sc = cm->cm_sc;
1662 mtx_assert(&sc->mfi_io_lock, MA_OWNED);
1663
1664 hdr = &cm->cm_frame->header;
1665
1666 if (sc->mfi_aen_cm == NULL)
1667 return;
1668
1669 if (sc->cm_aen_abort ||
1670 hdr->cmd_status == MFI_STAT_INVALID_STATUS) {
1671 sc->cm_aen_abort = 0;
1672 aborted = 1;
1673 } else {
1674 sc->mfi_aen_triggered = 1;
1675 if (sc->mfi_poll_waiting) {
1676 sc->mfi_poll_waiting = 0;
1677 selwakeup(&sc->mfi_select);
1678 }
1679 detail = cm->cm_data;

--- 702 unchanged lines hidden (view full) ---

2382 abort->abort_context = cm_abort->cm_frame->header.context;
2383 abort->abort_mfi_addr_lo = (uint32_t)cm_abort->cm_frame_busaddr;
2384 abort->abort_mfi_addr_hi =
2385 (uint32_t)((uint64_t)cm_abort->cm_frame_busaddr >> 32);
2386 cm->cm_data = NULL;
2387 cm->cm_flags = MFI_CMD_POLLED;
2388
2389 if (sc->mfi_aen_cm)
2390 sc->cm_aen_abort = 1;
2391 if (sc->mfi_map_sync_cm)
2392 sc->cm_map_abort = 1;
2393 mfi_mapcmd(sc, cm);
2394 mfi_release_command(cm);
2395
2396 while (i < 5 && sc->mfi_aen_cm != NULL) {
2397 msleep(&sc->mfi_aen_cm, &sc->mfi_io_lock, 0, "mfiabort",
2398 5 * hz);
2399 i++;
2400 }
2401 while (i < 5 && sc->mfi_map_sync_cm != NULL) {
2402 msleep(&sc->mfi_map_sync_cm, &sc->mfi_io_lock, 0, "mfiabort",
2403 5 * hz);
2404 i++;
2405 }
2406
2407 return (0);
2408}
2409
2410int
2411mfi_dump_blocks(struct mfi_softc *sc, int id, uint64_t lba, void *virt,
2412 int len)
2413{

--- 1139 unchanged lines hidden (view full) ---

3553 if (sc->adpreset == 0) {
3554 if (!mfi_tbolt_reset(sc)) {
3555 callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz, mfi_timeout, sc);
3556 return;
3557 }
3558 }
3559 mtx_lock(&sc->mfi_io_lock);
3560 TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {
3561 if (sc->mfi_aen_cm == cm || sc->mfi_map_sync_cm == cm)
3562 continue;
3563 if (cm->cm_timestamp < deadline) {
3564 if (sc->adpreset != 0 && sc->issuepend_done == 0) {
3565 cm->cm_timestamp = time_uptime;
3566 } else {
3567 device_printf(sc->mfi_dev,
3568 "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
3569 cm, (int)(time_uptime - cm->cm_timestamp)
3570 );
3571 MFI_PRINT_CMD(cm);

--- 20 unchanged lines hidden ---