501 }
502
503
504 /*
505 * hermon_eq_poll
506 * Context: Only called from interrupt context (and during panic)
507 */
508 static void
509 hermon_eq_poll(hermon_state_t *state, hermon_eqhdl_t eq)
510 {
511 hermon_hw_eqe_t *eqe;
512 int polled_some;
513 uint32_t cons_indx, wrap_around_mask, shift;
514 int (*eqfunction)(hermon_state_t *state, hermon_eqhdl_t eq,
515 hermon_hw_eqe_t *eqe);
516 ddi_acc_handle_t uarhdl = hermon_get_uarhdl(state);
517
518 /* initialize the FMA retry loop */
519 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
520
521 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*eq))
522
523 /* Get the consumer pointer index */
524 cons_indx = eq->eq_consindx;
525 shift = eq->eq_log_eqsz - HERMON_EQE_OWNER_SHIFT;
526
527 /*
528 * Calculate the wrap around mask. Note: This operation only works
529 * because all Hermon event queues have power-of-2 sizes
530 */
531 wrap_around_mask = (eq->eq_bufsz - 1);
532
533 /* Calculate the pointer to the first EQ entry */
534 eqe = &eq->eq_buf[(cons_indx & wrap_around_mask)];
535
536
537 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*eqe))
538
539 /*
540 * Pull the handler function for this EQ from the Hermon Event Queue
541 * handle
542 */
543 eqfunction = eq->eq_func;
544
545 for (;;) {
546 polled_some = 0;
547 while (HERMON_EQE_OWNER_IS_SW(eq, eqe, cons_indx, shift)) {
548
549 /*
550 * Call the EQ handler function. But only call if we
551 * are not in polled I/O mode (i.e. not processing
552 * because of a system panic). Note: We don't call
553 * the EQ handling functions from a system panic
554 * because we are primarily concerned only with
555 * ensuring that the event queues do not overflow (or,
556 * more specifically, the event queue associated with
557 * the CQ that is being used in the sync/dump process).
558 * Also, we don't want to make any upcalls (to the
793 * Register the memory for the EQ.
794 *
795 * Because we are in the attach path we use NOSLEEP here so that we
796 * SPIN in the HCR since the event queues are not setup yet, and we
797 * cannot NOSPIN at this point in time.
798 */
799
800 mr_attr.mr_vaddr = (uint64_t)(uintptr_t)buf;
801 mr_attr.mr_len = eq->eq_eqinfo.qa_size;
802 mr_attr.mr_as = NULL;
803 mr_attr.mr_flags = IBT_MR_NOSLEEP | IBT_MR_ENABLE_LOCAL_WRITE;
804 op.mro_bind_type = state->hs_cfg_profile->cp_iommu_bypass;
805 op.mro_bind_dmahdl = eq->eq_eqinfo.qa_dmahdl;
806 op.mro_bind_override_addr = 0;
807 status = hermon_mr_register(state, pd, &mr_attr, &mr, &op,
808 HERMON_EQ_CMPT);
809 if (status != DDI_SUCCESS) {
810 status = DDI_FAILURE;
811 goto eqalloc_fail4;
812 }
813 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*mr))
814
815 /*
816 * Fill in the EQC entry. This is the final step before passing
817 * ownership of the EQC entry to the Hermon hardware. We use all of
818 * the information collected/calculated above to fill in the
819 * requisite portions of the EQC. Note: We create all EQs in the
820 * "fired" state. We will arm them later (after our interrupt
821 * routine had been registered.)
822 */
823 bzero(&eqc_entry, sizeof (hermon_hw_eqc_t));
824 eqc_entry.state = HERMON_EQ_ARMED;
825 eqc_entry.log_eq_sz = log_eq_size;
826 eqc_entry.intr = intr;
827 eqc_entry.log2_pgsz = mr->mr_log2_pgsz;
828 eqc_entry.pg_offs = eq->eq_eqinfo.qa_pgoffs >> 5;
829 eqc_entry.mtt_base_addrh = (uint32_t)((mr->mr_mttaddr >> 32) & 0xFF);
830 eqc_entry.mtt_base_addrl = mr->mr_mttaddr >> 3;
831 eqc_entry.cons_indx = 0x0;
832 eqc_entry.prod_indx = 0x0;
833
|
501 }
502
503
504 /*
505 * hermon_eq_poll
506 * Context: Only called from interrupt context (and during panic)
507 */
508 static void
509 hermon_eq_poll(hermon_state_t *state, hermon_eqhdl_t eq)
510 {
511 hermon_hw_eqe_t *eqe;
512 int polled_some;
513 uint32_t cons_indx, wrap_around_mask, shift;
514 int (*eqfunction)(hermon_state_t *state, hermon_eqhdl_t eq,
515 hermon_hw_eqe_t *eqe);
516 ddi_acc_handle_t uarhdl = hermon_get_uarhdl(state);
517
518 /* initialize the FMA retry loop */
519 hermon_pio_init(fm_loop_cnt, fm_status, fm_test);
520
521 /* Get the consumer pointer index */
522 cons_indx = eq->eq_consindx;
523 shift = eq->eq_log_eqsz - HERMON_EQE_OWNER_SHIFT;
524
525 /*
526 * Calculate the wrap around mask. Note: This operation only works
527 * because all Hermon event queues have power-of-2 sizes
528 */
529 wrap_around_mask = (eq->eq_bufsz - 1);
530
531 /* Calculate the pointer to the first EQ entry */
532 eqe = &eq->eq_buf[(cons_indx & wrap_around_mask)];
533
534
535 /*
536 * Pull the handler function for this EQ from the Hermon Event Queue
537 * handle
538 */
539 eqfunction = eq->eq_func;
540
541 for (;;) {
542 polled_some = 0;
543 while (HERMON_EQE_OWNER_IS_SW(eq, eqe, cons_indx, shift)) {
544
545 /*
546 * Call the EQ handler function. But only call if we
547 * are not in polled I/O mode (i.e. not processing
548 * because of a system panic). Note: We don't call
549 * the EQ handling functions from a system panic
550 * because we are primarily concerned only with
551 * ensuring that the event queues do not overflow (or,
552 * more specifically, the event queue associated with
553 * the CQ that is being used in the sync/dump process).
554 * Also, we don't want to make any upcalls (to the
789 * Register the memory for the EQ.
790 *
791 * Because we are in the attach path we use NOSLEEP here so that we
792 * SPIN in the HCR since the event queues are not setup yet, and we
793 * cannot NOSPIN at this point in time.
794 */
795
796 mr_attr.mr_vaddr = (uint64_t)(uintptr_t)buf;
797 mr_attr.mr_len = eq->eq_eqinfo.qa_size;
798 mr_attr.mr_as = NULL;
799 mr_attr.mr_flags = IBT_MR_NOSLEEP | IBT_MR_ENABLE_LOCAL_WRITE;
800 op.mro_bind_type = state->hs_cfg_profile->cp_iommu_bypass;
801 op.mro_bind_dmahdl = eq->eq_eqinfo.qa_dmahdl;
802 op.mro_bind_override_addr = 0;
803 status = hermon_mr_register(state, pd, &mr_attr, &mr, &op,
804 HERMON_EQ_CMPT);
805 if (status != DDI_SUCCESS) {
806 status = DDI_FAILURE;
807 goto eqalloc_fail4;
808 }
809
810 /*
811 * Fill in the EQC entry. This is the final step before passing
812 * ownership of the EQC entry to the Hermon hardware. We use all of
813 * the information collected/calculated above to fill in the
814 * requisite portions of the EQC. Note: We create all EQs in the
815 * "fired" state. We will arm them later (after our interrupt
816 * routine had been registered.)
817 */
818 bzero(&eqc_entry, sizeof (hermon_hw_eqc_t));
819 eqc_entry.state = HERMON_EQ_ARMED;
820 eqc_entry.log_eq_sz = log_eq_size;
821 eqc_entry.intr = intr;
822 eqc_entry.log2_pgsz = mr->mr_log2_pgsz;
823 eqc_entry.pg_offs = eq->eq_eqinfo.qa_pgoffs >> 5;
824 eqc_entry.mtt_base_addrh = (uint32_t)((mr->mr_mttaddr >> 32) & 0xFF);
825 eqc_entry.mtt_base_addrl = mr->mr_mttaddr >> 3;
826 eqc_entry.cons_indx = 0x0;
827 eqc_entry.prod_indx = 0x0;
828
|