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 --- |