IB/hfi1: Remove UI char device

Remove UI char device which exposes direct access to registers for user
space. This was put in to aid in debugging the hardware. We are looking
into alternatives means of providing the same functionality. This
removes another char device from HFI1's footprint.

Reviewed-by: Dean Luick <dean.luick@intel.com>
Reviewed-by: Mitko Haralanov <mitko.haralanov@intel.com>
Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Dennis Dalessandro 2016-05-19 05:25:57 -07:00 committed by Doug Ledford
parent 0eb626590d
commit 7312f29d8e
1 changed files with 1 additions and 167 deletions

View File

@ -1497,163 +1497,10 @@ static int set_ctxt_pkey(struct hfi1_ctxtdata *uctxt, unsigned subctxt,
return ret;
}
static int ui_open(struct inode *inode, struct file *filp)
{
struct hfi1_devdata *dd;
dd = container_of(inode->i_cdev, struct hfi1_devdata, ui_cdev);
filp->private_data = dd; /* for other methods */
return 0;
}
static int ui_release(struct inode *inode, struct file *filp)
{
/* nothing to do */
return 0;
}
static loff_t ui_lseek(struct file *filp, loff_t offset, int whence)
{
struct hfi1_devdata *dd = filp->private_data;
return fixed_size_llseek(filp, offset, whence,
(dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE);
}
/* NOTE: assumes unsigned long is 8 bytes */
static ssize_t ui_read(struct file *filp, char __user *buf, size_t count,
loff_t *f_pos)
{
struct hfi1_devdata *dd = filp->private_data;
void __iomem *base = dd->kregbase;
unsigned long total, csr_off,
barlen = (dd->kregend - dd->kregbase);
u64 data;
/* only read 8 byte quantities */
if ((count % 8) != 0)
return -EINVAL;
/* offset must be 8-byte aligned */
if ((*f_pos % 8) != 0)
return -EINVAL;
/* destination buffer must be 8-byte aligned */
if ((unsigned long)buf % 8 != 0)
return -EINVAL;
/* must be in range */
if (*f_pos + count > (barlen + DC8051_DATA_MEM_SIZE))
return -EINVAL;
/* only set the base if we are not starting past the BAR */
if (*f_pos < barlen)
base += *f_pos;
csr_off = *f_pos;
for (total = 0; total < count; total += 8, csr_off += 8) {
/* accessing LCB CSRs requires more checks */
if (is_lcb_offset(csr_off)) {
if (read_lcb_csr(dd, csr_off, (u64 *)&data))
break; /* failed */
}
/*
* Cannot read ASIC GPIO/QSFP* clear and force CSRs without a
* false parity error. Avoid the whole issue by not reading
* them. These registers are defined as having a read value
* of 0.
*/
else if (csr_off == ASIC_GPIO_CLEAR ||
csr_off == ASIC_GPIO_FORCE ||
csr_off == ASIC_QSFP1_CLEAR ||
csr_off == ASIC_QSFP1_FORCE ||
csr_off == ASIC_QSFP2_CLEAR ||
csr_off == ASIC_QSFP2_FORCE)
data = 0;
else if (csr_off >= barlen) {
/*
* read_8051_data can read more than just 8 bytes at
* a time. However, folding this into the loop and
* handling the reads in 8 byte increments allows us
* to smoothly transition from chip memory to 8051
* memory.
*/
if (read_8051_data(dd,
(u32)(csr_off - barlen),
sizeof(data), &data))
break; /* failed */
} else
data = readq(base + total);
if (put_user(data, (unsigned long __user *)(buf + total)))
break;
}
*f_pos += total;
return total;
}
/* NOTE: assumes unsigned long is 8 bytes */
static ssize_t ui_write(struct file *filp, const char __user *buf,
size_t count, loff_t *f_pos)
{
struct hfi1_devdata *dd = filp->private_data;
void __iomem *base;
unsigned long total, data, csr_off;
int in_lcb;
/* only write 8 byte quantities */
if ((count % 8) != 0)
return -EINVAL;
/* offset must be 8-byte aligned */
if ((*f_pos % 8) != 0)
return -EINVAL;
/* source buffer must be 8-byte aligned */
if ((unsigned long)buf % 8 != 0)
return -EINVAL;
/* must be in range */
if (*f_pos + count > dd->kregend - dd->kregbase)
return -EINVAL;
base = (void __iomem *)dd->kregbase + *f_pos;
csr_off = *f_pos;
in_lcb = 0;
for (total = 0; total < count; total += 8, csr_off += 8) {
if (get_user(data, (unsigned long __user *)(buf + total)))
break;
/* accessing LCB CSRs requires a special procedure */
if (is_lcb_offset(csr_off)) {
if (!in_lcb) {
int ret = acquire_lcb_access(dd, 1);
if (ret)
break;
in_lcb = 1;
}
} else {
if (in_lcb) {
release_lcb_access(dd, 1);
in_lcb = 0;
}
}
writeq(data, base + total);
}
if (in_lcb)
release_lcb_access(dd, 1);
*f_pos += total;
return total;
}
static const struct file_operations ui_file_ops = {
.owner = THIS_MODULE,
.llseek = ui_lseek,
.read = ui_read,
.write = ui_write,
.open = ui_open,
.release = ui_release,
};
#define UI_OFFSET 192 /* device minor offset for UI devices */
static int create_ui = 1;
static void user_remove(struct hfi1_devdata *dd)
{
hfi1_cdev_cleanup(&dd->user_cdev, &dd->user_device);
hfi1_cdev_cleanup(&dd->ui_cdev, &dd->ui_device);
}
static int user_add(struct hfi1_devdata *dd)
@ -1666,21 +1513,8 @@ static int user_add(struct hfi1_devdata *dd)
&dd->user_cdev, &dd->user_device,
true);
if (ret)
goto done;
user_remove(dd);
if (create_ui) {
snprintf(name, sizeof(name),
"%s_ui%d", class_name(), dd->unit);
ret = hfi1_cdev_init(dd->unit + UI_OFFSET, name, &ui_file_ops,
&dd->ui_cdev, &dd->ui_device,
false);
if (ret)
goto done;
}
return 0;
done:
user_remove(dd);
return ret;
}