Beispiel #1
0
void
sda_slot_handle_detect(sda_slot_t *slot)
{
	uint32_t	inserted;

	sda_slot_enter(slot);

	slot->s_stamp = ddi_get_time();
	slot->s_intransit = 1;
	slot->s_flags = 0;
	slot->s_rca = 0;
	slot->s_ready = B_FALSE;

	sda_getprop(slot, SDA_PROP_INSERTED, &inserted);
	slot->s_inserted = (inserted != 0);

	if (slot->s_inserted && !slot->s_failed) {
		/*
		 * We need to initialize the card, so we only support
		 * hipri commands for now.
		 */
		slot->s_init = B_TRUE;
		sda_slot_exit(slot);

		/*
		 * Card insertion occurred.  We have to run this on
		 * another task, to avoid deadlock as the task may
		 * need to dispatch commands.
		 */

		(void) ddi_taskq_dispatch(slot->s_hp_tq, sda_slot_insert, slot,
		    DDI_SLEEP);
	} else {

		/*
		 * Nuke in-flight commands.
		 */
		sda_slot_abort(slot, SDA_ENODEV);

		/*
		 * Restart the slot (incl. power cycle).  This gets the
		 * slot to a known good state.
		 */
		sda_slot_reset(slot);

		slot->s_intransit = 0;
		sda_slot_exit(slot);

		bd_state_change(slot->s_bdh);
	}

	sda_slot_wakeup(slot);
}
Beispiel #2
0
void
sda_slot_insert(void *arg)
{
	sda_slot_t	*slot = arg;

	if (sda_init_card(slot) != SDA_EOK) {
		/*
		 * Remove power from the slot.  If a more severe fault
		 * occurred, then a manual reset with cfgadm will be needed.
		 */
		sda_slot_err(slot, "Unable to initialize card!");
		sda_slot_enter(slot);
		sda_slot_power_off(slot);
		sda_slot_abort(slot, SDA_ENODEV);
		sda_slot_exit(slot);

	} else if ((slot->s_flags & SLOTF_MEMORY) == 0) {
		/*
		 * SDIO: For SDIO, we can write the card's
		 * MANFID tuple in CIS to the UUID.  Until we
		 * support SDIO, we just suppress creating
		 * devinfo nodes.
		 */
		sda_slot_err(slot, "Non-memory target not supported");
	} else {

		sda_slot_enter(slot);
		if (sda_mem_parse_cid_csd(slot) != DDI_SUCCESS) {
			sda_slot_err(slot,
			    "Unable to parse card identification");
		} else {
			slot->s_warn = B_FALSE;
			slot->s_ready = B_TRUE;
		}
		sda_slot_exit(slot);
	}

	slot->s_stamp = ddi_get_time();
	slot->s_intransit = 0;
	bd_state_change(slot->s_bdh);
}
void
sda_slot_insert(void *arg)
{
	sda_slot_t	*slot = arg;

	if (sda_init_card(slot) != SDA_EOK) {
		/*
		 * Remove power from the slot.  If a more severe fault
		 * occurred, then a manual reset with cfgadm will be needed.
		 */
		sda_slot_err(slot, "Unable to initialize card!");
		sda_slot_enter(slot);
		sda_slot_power_off(slot);
		sda_slot_abort(slot, SDA_ENODEV);
		sda_slot_exit(slot);
		sda_nexus_remove(slot);

	} else {
		sda_nexus_insert(slot);
	}

	slot->s_stamp = ddi_get_time();
	slot->s_intransit = 0;
}
Beispiel #4
0
int
ac_add_memory(ac_cfga_pkt_t *pkt)
{
	struct bd_list *board;
	struct ac_mem_info *mem_info;
	int force = pkt->cmd_cfga.force;
	int retval;

	board = fhc_bdlist_lock(pkt->softsp->board);
	if (board == NULL || board->ac_softsp == NULL) {
		fhc_bdlist_unlock();
		AC_ERR_SET(pkt, AC_ERR_BD);
		return (EINVAL);
	}
	ASSERT(pkt->softsp == board->ac_softsp);

	/* verify the board is of the correct type */
	switch (board->sc.type) {
	case CPU_BOARD:
	case MEM_BOARD:
		break;
	default:
		fhc_bdlist_unlock();
		AC_ERR_SET(pkt, AC_ERR_BD_TYPE);
		return (EINVAL);
	}

	/* verify the memory condition is acceptable */
	mem_info = &pkt->softsp->bank[pkt->bank];
	if (!MEM_BOARD_VISIBLE(board) || mem_info->busy ||
	    fhc_bd_busy(pkt->softsp->board) ||
	    mem_info->rstate != SYSC_CFGA_RSTATE_CONNECTED ||
	    mem_info->ostate != SYSC_CFGA_OSTATE_UNCONFIGURED ||
	    (!force && mem_info->condition != SYSC_CFGA_COND_OK)) {
		fhc_bdlist_unlock();
		AC_ERR_SET(pkt, AC_ERR_BD_STATE);
		return (EINVAL);
	}

	/*
	 * at this point, we have an available bank to add.
	 * mark it busy and initiate the add function.
	 */
	mem_info->busy = TRUE;
	fhc_bdlist_unlock();

	retval = ac_add_bank(board, pkt);

	/*
	 * We made it!  Update the status and get out of here.
	 */
	(void) fhc_bdlist_lock(-1);
	mem_info->busy = FALSE;
	if (retval == 0) {
		mem_info->ostate = SYSC_CFGA_OSTATE_CONFIGURED;
		mem_info->status_change = ddi_get_time();
	}

	fhc_bdlist_unlock();

	if (retval != 0) {
		return (retval);
	}
	return (DDI_SUCCESS);
}