static void pet_get(ipmi_pet_t *pet) { pet_lock(pet); pet_get_nolock(pet); pet_unlock(pet); }
static int destroy_pet(void *cb_data, void *item1, void *item2) { ipmi_pet_t *pet = item1; pet_lock(pet); pet->in_list = 0; pet_unlock(pet); return LOCKED_LIST_ITER_CONTINUE; }
static void pef_unlocked(ipmi_pef_t *pef, int err, void *cb_data) { ipmi_pet_t *pet = cb_data; pet_lock(pet); ipmi_pef_destroy(pet->pef, NULL, NULL); pet->pef = NULL; pet_op_done(pet); }
static void lanparm_unlocked(ipmi_lanparm_t *lanparm, int err, void *cb_data) { ipmi_pet_t *pet = cb_data; pet_lock(pet); ipmi_lanparm_destroy(pet->lanparm, NULL, NULL); pet->lanparm = NULL; pet_op_done(pet); }
static void internal_pet_destroy(ipmi_pet_t *pet) { os_handler_t *os_hnd = pet->timer_info->os_hnd; if (pet->in_list) { ipmi_domain_attr_t *attr; locked_list_t *pets; int rv; rv = ipmi_domain_id_find_attribute(pet->domain, IPMI_PET_ATTR_NAME, &attr); if (!rv) { pet->refcount++; pet->in_list = 0; pet_unlock(pet); pets = ipmi_domain_attr_get_data(attr); locked_list_remove(pets, pet, NULL); ipmi_domain_attr_put(attr); pet_lock(pet); /* While we were unlocked, someone may have come in and grabbed the PET by iterating the list of PETs. That's ok, we just let them handle the destruction since this code will not be entered again. */ if (pet->refcount != 1) { pet->refcount--; pet_unlock(pet); return; } } } pet_unlock(pet); if (os_hnd->stop_timer(os_hnd, pet->timer) == 0) { ipmi_destroy_lock(pet->timer_info->lock); os_hnd->free_timer(os_hnd, pet->timer); ipmi_mem_free(pet->timer_info); } else { pet->timer_info->cancelled = 1; } if (pet->destroy_done) { pet->destroy_done(pet, 0, pet->destroy_cb_data); } ipmi_mem_free(pet); }
static void pef_locked(ipmi_pef_t *pef, int err, void *cb_data) { ipmi_pet_t *pet = cb_data; int rv; pet_lock(pet); if (pet->destroyed) { pef_op_done(pet, ECANCELED); goto out; } if (err == 0x80) { /* No support for locking, just set it so and continue. */ pet->pef_lock_broken = 1; } else if (err) { ipmi_log(IPMI_LOG_WARNING, "pet.c(pef_locked): PEF lock failed: 0x%x", err); pef_op_done(pet, err); goto out; } /* Start the configuration process. */ rv = ipmi_pef_get_parm(pet->pef, pet->pef_check[0].conf_num, pet->pef_check[0].set, 0, pef_got_config, pet); if (rv) { ipmi_log(IPMI_LOG_WARNING, "pet.c(pef_locked): PEF control get err: 0x%x", rv); pef_op_done(pet, rv); goto out; } pet_unlock(pet); out: return; }
static int start_pet_setup(ipmi_mc_t *mc, ipmi_pet_t *pet) { int rv = 0; pet_lock(pet); if (pet->in_progress) { pet_unlock(pet); return EAGAIN; } pet->pet = pet; pet->pef_lock_broken = 0; pet->pef_err = 0; pet->changed_pef = 0; pet->lanparm_lock_broken = 0; pet->lanparm_err = 0; pet->changed_lanparm = 0; pet->pef_check_pos = 0; pet->in_progress++; pet_get_nolock(pet); rv = ipmi_pef_alloc(mc, pef_alloced, pet, &pet->pef); if (rv) { pet->in_progress--; pet_put_nolock(pet); ipmi_log(IPMI_LOG_WARNING, "start_pet_setup: Unable to allocate pef: 0x%x", rv); goto out; } /* Now that we have the channel, set up the lan parms. */ pet->lanparm_check_pos = 0; rv = ipmi_lanparm_alloc(mc, pet->channel, &(pet->lanparm)); if (rv) { ipmi_log(IPMI_LOG_WARNING, "start_pet_setup: Unable to allocate lanparm: 0x%x", rv); } else { pet->in_progress++; pet_get_nolock(pet); rv = ipmi_lanparm_get_parm(pet->lanparm, IPMI_LANPARM_DEST_TYPE, pet->lan_dest_sel, 0, lanparm_got_config, pet); if (rv) { pet->in_progress--; pet_put_nolock(pet); ipmi_log(IPMI_LOG_WARNING, "start_pet_setup: Unable to get dest type: 0x%x", rv); ipmi_lanparm_destroy(pet->lanparm, NULL, NULL); pet->lanparm = NULL; } } rv = 0; /* We continue with the PEF run, even if the lanparm fails. */ out: pet_unlock(pet); return rv; }
static void pef_got_config(ipmi_pef_t *pef, int err, unsigned char *data, unsigned int data_len, void *cb_data) { ipmi_pet_t *pet = cb_data; unsigned char val[22]; int rv; int pos; parm_check_t *check; int check_failed = 0; unsigned int i; pet_lock(pet); if (pet->destroyed) { pef_op_done(pet, ECANCELED); goto out; } if (err) { ipmi_log(IPMI_LOG_WARNING, "pet.c(pef_got_control): PEF alloc failed: 0x%x", err); pef_op_done(pet, err); goto out; } pos = pet->pef_check_pos; check = &(pet->pef_check[pos]); /* Don't forget to skip the revision number in the length. */ if (data_len < check->data_len) { ipmi_log(IPMI_LOG_WARNING, "pet.c(pef_got_cofnfig): PEF data length too short for" " config %d, was %d, expected %d", check->conf_num, data_len, check->data_len); pef_op_done(pet, EINVAL); goto out; } data++; /* Skip the revision number */ /* Check the config item we got and make sure it matches. If it does not match, send the proper data for it. */ for (i=0; i<check->data_len; i++) { if ((data[i] & check->mask[i]) != check->data[i]) { check_failed = 1; break; } } if (check_failed) { for (i=0; i<check->data_len; i++) val[i] = (data[i] & ~check->mask[i]) | check->data[i]; rv = ipmi_pef_set_parm(pef, check->conf_num, val, check->data_len, pef_set_config, pet); if (rv) { ipmi_log(IPMI_LOG_WARNING, "pet.c(pef_got_config): PEF error sending set: 0x%x", rv); pef_op_done(pet, rv); goto out; } pet->changed_pef = 1; } else { rv = pef_next_config(pet); if (rv) { pef_op_done(pet, rv); goto out; } } pet_unlock(pet); out: return; }
static void pet_put(ipmi_pet_t *pet) { pet_lock(pet); pet_put_locked(pet); }