int mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n) { int i, ret = 0; struct islpci_mgmtframe *response; for (i = 0; i < n; i++) { struct oid_t *t = &(isl_oid[l[i]]); void *data = priv->mib[l[i]]; int j = 0; u32 oid = t->oid; BUG_ON(data == NULL); while (j <= t->range) { int r = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, data, t->size, &response); if (response) { r |= (response->header->operation == PIMFOR_OP_ERROR); islpci_mgt_release(response); } if (r) printk(KERN_ERR "%s: mgt_commit_list: failure. " "oid=%08x err=%d\n", priv->ndev->name, oid, r); ret |= r; j++; oid++; data += t->size; } } return ret; }
int mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len) { int ret = 0; struct islpci_mgmtframe *response; int response_op = PIMFOR_OP_ERROR; int dlen; u32 oid; BUG_ON(OID_NUM_LAST <= n); dlen = isl_oid[n].size; oid = isl_oid[n].oid; mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, data); if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, data, dlen + extra_len, &response); if (!ret) { response_op = response->header->operation; islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) ret = -EIO; } else ret = -EIO; if (data) mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data); return ret; }
int mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) { int ret = 0; struct islpci_mgmtframe *response = NULL; int response_op = PIMFOR_OP_ERROR; int dlen; void *cache, *_data = data; u32 oid; BUG_ON(OID_NUM_LAST <= n); BUG_ON(extra > isl_oid[n].range); if (!priv->mib) /* memory has been freed */ return -1; dlen = isl_oid[n].size; cache = priv->mib[n]; cache += (cache ? extra * dlen : 0); oid = isl_oid[n].oid + extra; if (_data == NULL) /* we are requested to re-set a cached value */ _data = cache; else mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, _data); /* If we are going to write to the cache, we don't want anyone to read * it -> acquire write lock. * Else we could acquire a read lock to be sure we don't bother the * commit process (which takes a write lock). But I'm not sure if it's * needed. */ if (cache) down_write(&priv->mib_sem); if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, _data, dlen, &response); if (!ret) { response_op = response->header->operation; islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) ret = -EIO; } else if (!cache) ret = -EIO; if (cache) { if (!ret && data) memcpy(cache, _data, dlen); up_write(&priv->mib_sem); } /* re-set given data to what it was */ if (data) mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data); return ret; }
int mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) { int ret = 0; struct islpci_mgmtframe *response = NULL; int response_op = PIMFOR_OP_ERROR; int dlen; void *cache, *_data = data; u32 oid; BUG_ON(OID_NUM_LAST <= n); BUG_ON(extra > isl_oid[n].range); if (!priv->mib) return -1; dlen = isl_oid[n].size; cache = priv->mib[n]; cache += (cache ? extra * dlen : 0); oid = isl_oid[n].oid + extra; if (_data == NULL) _data = cache; else mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, _data); if (cache) down_write(&priv->mib_sem); if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, _data, dlen, &response); if (!ret) { response_op = response->header->operation; islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) ret = -EIO; } else if (!cache) ret = -EIO; if (cache) { if (!ret && data) memcpy(cache, _data, dlen); up_write(&priv->mib_sem); } if (data) mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data); return ret; }
static int mgt_update_addr(islpci_private *priv) { struct islpci_mgmtframe *res; int ret; ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, isl_oid[GEN_OID_MACADDRESS].oid, NULL, isl_oid[GEN_OID_MACADDRESS].size, &res); if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR)) memcpy(priv->ndev->dev_addr, res->data, 6); else ret = -EIO; if (res) islpci_mgt_release(res); if (ret) printk(KERN_ERR "%s: mgt_update_addr: failure\n", priv->ndev->name); return ret; }
int mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data, union oid_res_t *res) { int ret = -EIO; int reslen = 0; struct islpci_mgmtframe *response = NULL; int dlen; void *cache, *_res = NULL; u32 oid; BUG_ON(OID_NUM_LAST <= n); BUG_ON(extra > isl_oid[n].range); res->ptr = NULL; if (!priv->mib) return -1; dlen = isl_oid[n].size; cache = priv->mib[n]; cache += cache ? extra * dlen : 0; oid = isl_oid[n].oid + extra; reslen = dlen; if (cache) down_read(&priv->mib_sem); if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, oid, data, dlen, &response); if (ret || !response || response->header->operation == PIMFOR_OP_ERROR) { if (response) islpci_mgt_release(response); ret = -EIO; } if (!ret) { _res = response->data; reslen = response->header->length; } } else if (cache) { _res = cache; ret = 0; } if ((isl_oid[n].flags & OID_FLAG_TYPE) == OID_TYPE_U32) res->u = ret ? 0 : le32_to_cpu(*(u32 *) _res); else { res->ptr = kmalloc(reslen, GFP_KERNEL); BUG_ON(res->ptr == NULL); if (ret) memset(res->ptr, 0, reslen); else { memcpy(res->ptr, _res, reslen); mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, res->ptr); } } if (cache) up_read(&priv->mib_sem); if (response && !ret) islpci_mgt_release(response); if (reslen > isl_oid[n].size) printk(KERN_DEBUG "mgt_get_request(0x%x): received data length was bigger " "than expected (%d > %d). Memory is probably corrupted...", oid, reslen, isl_oid[n].size); return ret; }