scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
scratch0 &= ~clear;
write_csr(dd, ASIC_CFG_SCRATCH, scratch0); /* force write to be visible to other HFI on another OS */
(void)read_csr(dd, ASIC_CFG_SCRATCH);
/* the checks below expect the position to be positive */ if (*ppos < 0) return -EINVAL;
tmp = kzalloc(DC8051_DATA_MEM_SIZE, GFP_KERNEL); if (!tmp) return -ENOMEM;
/* * Fill in the requested portion of the temporary buffer from the * 8051 memory. The 8051 memory read is done in terms of 8 bytes. * Adjust start and end to fit. Skip reading anything if out of * range.
*/
start = *ppos & ~0x7; /* round down */ if (start < DC8051_DATA_MEM_SIZE) {
end = (*ppos + count + 7) & ~0x7; /* round up */ if (end > DC8051_DATA_MEM_SIZE)
end = DC8051_DATA_MEM_SIZE;
rval = read_8051_data(ppd->dd, start, end - start,
(u64 *)(tmp + start)); if (rval) goto done;
}
if (*ppos < 0) return -EINVAL; /* only read 8 byte quantities */ if ((count % 8) != 0) return -EINVAL; /* offset must be 8-byte aligned */ if ((*ppos % 8) != 0) return -EINVAL; /* do nothing if out of range or zero count */ if (*ppos >= (LCB_END - LCB_START) || !count) return 0; /* reduce count if needed */ if (*ppos + count > LCB_END - LCB_START)
count = (LCB_END - LCB_START) - *ppos;
csr_off = LCB_START + *ppos; for (total = 0; total < count; total += 8, csr_off += 8) { if (read_lcb_csr(dd, csr_off, (u64 *)&data)) break; /* failed */ if (put_user(data, (unsignedlong __user *)(buf + total))) break;
}
*ppos += total; return total;
}
if (*ppos < 0) return -EINVAL; /* only write 8 byte quantities */ if ((count % 8) != 0) return -EINVAL; /* offset must be 8-byte aligned */ if ((*ppos % 8) != 0) return -EINVAL; /* do nothing if out of range or zero count */ if (*ppos >= (LCB_END - LCB_START) || !count) return 0; /* reduce count if needed */ if (*ppos + count > LCB_END - LCB_START)
count = (LCB_END - LCB_START) - *ppos;
csr_off = LCB_START + *ppos; for (total = 0; total < count; total += 8, csr_off += 8) { if (get_user(data, (unsignedlong __user *)(buf + total))) break; if (write_lcb_csr(dd, csr_off, data)) break; /* failed */
}
*ppos += total; return total;
}
/* * read the per-port QSFP data for ppd
*/ static ssize_t qsfp_debugfs_dump(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ struct hfi1_pportdata *ppd; char *tmp; int ret;
ret = qsfp_dump(ppd, tmp, PAGE_SIZE); if (ret > 0)
ret = simple_read_from_buffer(buf, count, ppos, tmp, ret);
kfree(tmp); return ret;
}
/* Do an i2c write operation on the chain for the given HFI. */ static ssize_t __i2c_debugfs_write(struct file *file, constchar __user *buf,
size_t count, loff_t *ppos, u32 target)
{ struct hfi1_pportdata *ppd; char *buff; int ret; int i2c_addr; int offset; int total_written;
/* explicitly reject invalid address 0 to catch cp and cat */ if (i2c_addr == 0) return -EINVAL;
buff = memdup_user(buf, count); if (IS_ERR(buff)) return PTR_ERR(buff);
total_written = i2c_write(ppd, target, i2c_addr, offset, buff, count); if (total_written < 0) {
ret = total_written; goto _free;
}
*ppos += total_written;
ret = total_written;
_free:
kfree(buff); return ret;
}
/* Do an i2c write operation on chain for HFI 0. */ static ssize_t i2c1_debugfs_write(struct file *file, constchar __user *buf,
size_t count, loff_t *ppos)
{ return __i2c_debugfs_write(file, buf, count, ppos, 0);
}
/* Do an i2c write operation on chain for HFI 1. */ static ssize_t i2c2_debugfs_write(struct file *file, constchar __user *buf,
size_t count, loff_t *ppos)
{ return __i2c_debugfs_write(file, buf, count, ppos, 1);
}
/* Do an i2c read operation on the chain for the given HFI. */ static ssize_t __i2c_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos, u32 target)
{ struct hfi1_pportdata *ppd; char *buff; int ret; int i2c_addr; int offset; int total_read;
/* explicitly reject invalid address 0 to catch cp and cat */ if (i2c_addr == 0) return -EINVAL;
buff = kmalloc(count, GFP_KERNEL); if (!buff) return -ENOMEM;
total_read = i2c_read(ppd, target, i2c_addr, offset, buff, count); if (total_read < 0) {
ret = total_read; goto _free;
}
*ppos += total_read;
ret = copy_to_user(buf, buff, total_read); if (ret > 0) {
ret = -EFAULT; goto _free;
}
ret = total_read;
_free:
kfree(buff); return ret;
}
/* Do an i2c read operation on chain for HFI 0. */ static ssize_t i2c1_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ return __i2c_debugfs_read(file, buf, count, ppos, 0);
}
/* Do an i2c read operation on chain for HFI 1. */ static ssize_t i2c2_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ return __i2c_debugfs_read(file, buf, count, ppos, 1);
}
/* Do a QSFP write operation on the i2c chain for the given HFI. */ static ssize_t __qsfp_debugfs_write(struct file *file, constchar __user *buf,
size_t count, loff_t *ppos, u32 target)
{ struct hfi1_pportdata *ppd; char *buff; int ret; int total_written;
if (*ppos + count > QSFP_PAGESIZE * 4) /* base page + page00-page03 */ return -EINVAL;
ppd = private2ppd(file);
buff = memdup_user(buf, count); if (IS_ERR(buff)) return PTR_ERR(buff);
total_written = qsfp_write(ppd, target, *ppos, buff, count); if (total_written < 0) {
ret = total_written; goto _free;
}
*ppos += total_written;
ret = total_written;
_free:
kfree(buff); return ret;
}
/* Do a QSFP write operation on i2c chain for HFI 0. */ static ssize_t qsfp1_debugfs_write(struct file *file, constchar __user *buf,
size_t count, loff_t *ppos)
{ return __qsfp_debugfs_write(file, buf, count, ppos, 0);
}
/* Do a QSFP write operation on i2c chain for HFI 1. */ static ssize_t qsfp2_debugfs_write(struct file *file, constchar __user *buf,
size_t count, loff_t *ppos)
{ return __qsfp_debugfs_write(file, buf, count, ppos, 1);
}
/* Do a QSFP read operation on the i2c chain for the given HFI. */ static ssize_t __qsfp_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos, u32 target)
{ struct hfi1_pportdata *ppd; char *buff; int ret; int total_read;
if (*ppos + count > QSFP_PAGESIZE * 4) { /* base page + page00-page03 */
ret = -EINVAL; goto _return;
}
ppd = private2ppd(file);
buff = kmalloc(count, GFP_KERNEL); if (!buff) {
ret = -ENOMEM; goto _return;
}
total_read = qsfp_read(ppd, target, *ppos, buff, count); if (total_read < 0) {
ret = total_read; goto _free;
}
*ppos += total_read;
ret = copy_to_user(buf, buff, total_read); if (ret > 0) {
ret = -EFAULT; goto _free;
}
ret = total_read;
_free:
kfree(buff);
_return: return ret;
}
/* Do a QSFP read operation on i2c chain for HFI 0. */ static ssize_t qsfp1_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ return __qsfp_debugfs_read(file, buf, count, ppos, 0);
}
/* Do a QSFP read operation on i2c chain for HFI 1. */ static ssize_t qsfp2_debugfs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ return __qsfp_debugfs_read(file, buf, count, ppos, 1);
}
/* * driver stats field names, one line per stat, single string. Used by * programs like hfistats to print the stats in a way which works for * different versions of drivers, without changing program source. * if hfi1_ib_stats changes, this needs to change. Names need to be * 12 chars or less (w/o newline), for proper display by hfistats utility.
*/ staticconstchar * const hfi1_statnames[] = { /* must be element 0*/ "KernIntr", "ErrorIntr", "Tx_Errs", "Rcv_Errs", "H/W_Errs", "NoPIOBufs", "CtxtsOpen", "RcvLen_Errs", "EgrBufFull", "EgrHdrFull"
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.