2
* Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
3
* Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
5
* This software is available to you under a choice of one of two
6
* licenses. You may choose to be licensed under the terms of the GNU
7
* General Public License (GPL) Version 2, available from the file
8
* COPYING in the main directory of this source tree, or the
9
* OpenIB.org BSD license below:
11
* Redistribution and use in source and binary forms, with or
12
* without modification, are permitted provided that the following
15
* - Redistributions of source code must retain the above
16
* copyright notice, this list of conditions and the following
19
* - Redistributions in binary form must reproduce the above
20
* copyright notice, this list of conditions and the following
21
* disclaimer in the documentation and/or other materials
22
* provided with the distribution.
24
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
* This file contains support for diagnostic functions. It is accessed by
36
* opening the ipath_diag device, normally minor number 129. Diagnostic use
37
* of the InfiniPath chip may render the chip or board unusable until the
38
* driver is unloaded, or in some cases, until the system is rebooted.
40
* Accesses to the chip through this interface are not similar to going
41
* through the /sys/bus/pci resource mmap interface.
45
#include <linux/pci.h>
46
#include <linux/vmalloc.h>
48
#include <asm/uaccess.h>
50
#include "ipath_kernel.h"
51
#include "ipath_common.h"
54
static int diag_set_link;
56
static int ipath_diag_open(struct inode *in, struct file *fp);
57
static int ipath_diag_release(struct inode *in, struct file *fp);
58
static ssize_t ipath_diag_read(struct file *fp, char __user *data,
59
size_t count, loff_t *off);
60
static ssize_t ipath_diag_write(struct file *fp, const char __user *data,
61
size_t count, loff_t *off);
63
static const struct file_operations diag_file_ops = {
65
.write = ipath_diag_write,
66
.read = ipath_diag_read,
67
.open = ipath_diag_open,
68
.release = ipath_diag_release
71
static ssize_t ipath_diagpkt_write(struct file *fp,
72
const char __user *data,
73
size_t count, loff_t *off);
75
static const struct file_operations diagpkt_file_ops = {
77
.write = ipath_diagpkt_write,
80
static atomic_t diagpkt_count = ATOMIC_INIT(0);
81
static struct cdev *diagpkt_cdev;
82
static struct device *diagpkt_dev;
84
int ipath_diag_add(struct ipath_devdata *dd)
89
if (atomic_inc_return(&diagpkt_count) == 1) {
90
ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR,
91
"ipath_diagpkt", &diagpkt_file_ops,
92
&diagpkt_cdev, &diagpkt_dev);
95
ipath_dev_err(dd, "Couldn't create ipath_diagpkt "
101
snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit);
103
ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name,
104
&diag_file_ops, &dd->diag_cdev,
107
ipath_dev_err(dd, "Couldn't create %s device: %d",
114
void ipath_diag_remove(struct ipath_devdata *dd)
116
if (atomic_dec_and_test(&diagpkt_count))
117
ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_dev);
119
ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_dev);
123
* ipath_read_umem64 - read a 64-bit quantity from the chip into user space
124
* @dd: the infinipath device
125
* @uaddr: the location to store the data in user memory
126
* @caddr: the source chip address (full pointer, not offset)
127
* @count: number of bytes to copy (multiple of 32 bits)
129
* This function also localizes all chip memory accesses.
130
* The copy should be written such that we read full cacheline packets
131
* from the chip. This is usually used for a single qword
133
* NOTE: This assumes the chip address is 64-bit aligned.
135
static int ipath_read_umem64(struct ipath_devdata *dd, void __user *uaddr,
136
const void __iomem *caddr, size_t count)
138
const u64 __iomem *reg_addr = caddr;
139
const u64 __iomem *reg_end = reg_addr + (count / sizeof(u64));
142
/* not very efficient, but it works for now */
143
if (reg_addr < dd->ipath_kregbase || reg_end > dd->ipath_kregend) {
147
while (reg_addr < reg_end) {
148
u64 data = readq(reg_addr);
149
if (copy_to_user(uaddr, &data, sizeof(u64))) {
154
uaddr += sizeof(u64);
162
* ipath_write_umem64 - write a 64-bit quantity to the chip from user space
163
* @dd: the infinipath device
164
* @caddr: the destination chip address (full pointer, not offset)
165
* @uaddr: the source of the data in user memory
166
* @count: the number of bytes to copy (multiple of 32 bits)
168
* This is usually used for a single qword
169
* NOTE: This assumes the chip address is 64-bit aligned.
172
static int ipath_write_umem64(struct ipath_devdata *dd, void __iomem *caddr,
173
const void __user *uaddr, size_t count)
175
u64 __iomem *reg_addr = caddr;
176
const u64 __iomem *reg_end = reg_addr + (count / sizeof(u64));
179
/* not very efficient, but it works for now */
180
if (reg_addr < dd->ipath_kregbase || reg_end > dd->ipath_kregend) {
184
while (reg_addr < reg_end) {
186
if (copy_from_user(&data, uaddr, sizeof(data))) {
190
writeq(data, reg_addr);
193
uaddr += sizeof(u64);
201
* ipath_read_umem32 - read a 32-bit quantity from the chip into user space
202
* @dd: the infinipath device
203
* @uaddr: the location to store the data in user memory
204
* @caddr: the source chip address (full pointer, not offset)
205
* @count: number of bytes to copy
207
* read 32 bit values, not 64 bit; for memories that only
208
* support 32 bit reads; usually a single dword.
210
static int ipath_read_umem32(struct ipath_devdata *dd, void __user *uaddr,
211
const void __iomem *caddr, size_t count)
213
const u32 __iomem *reg_addr = caddr;
214
const u32 __iomem *reg_end = reg_addr + (count / sizeof(u32));
217
if (reg_addr < (u32 __iomem *) dd->ipath_kregbase ||
218
reg_end > (u32 __iomem *) dd->ipath_kregend) {
222
/* not very efficient, but it works for now */
223
while (reg_addr < reg_end) {
224
u32 data = readl(reg_addr);
225
if (copy_to_user(uaddr, &data, sizeof(data))) {
231
uaddr += sizeof(u32);
240
* ipath_write_umem32 - write a 32-bit quantity to the chip from user space
241
* @dd: the infinipath device
242
* @caddr: the destination chip address (full pointer, not offset)
243
* @uaddr: the source of the data in user memory
244
* @count: number of bytes to copy
246
* write 32 bit values, not 64 bit; for memories that only
247
* support 32 bit write; usually a single dword.
250
static int ipath_write_umem32(struct ipath_devdata *dd, void __iomem *caddr,
251
const void __user *uaddr, size_t count)
253
u32 __iomem *reg_addr = caddr;
254
const u32 __iomem *reg_end = reg_addr + (count / sizeof(u32));
257
if (reg_addr < (u32 __iomem *) dd->ipath_kregbase ||
258
reg_end > (u32 __iomem *) dd->ipath_kregend) {
262
while (reg_addr < reg_end) {
264
if (copy_from_user(&data, uaddr, sizeof(data))) {
268
writel(data, reg_addr);
271
uaddr += sizeof(u32);
278
static int ipath_diag_open(struct inode *in, struct file *fp)
280
int unit = iminor(in) - IPATH_DIAG_MINOR_BASE;
281
struct ipath_devdata *dd;
284
mutex_lock(&ipath_mutex);
286
if (ipath_diag_inuse) {
291
dd = ipath_lookup(unit);
293
if (dd == NULL || !(dd->ipath_flags & IPATH_PRESENT) ||
294
!dd->ipath_kregbase) {
299
fp->private_data = dd;
300
ipath_diag_inuse = -2;
304
/* Only expose a way to reset the device if we
305
make it into diag mode. */
306
ipath_expose_reset(&dd->pcidev->dev);
309
mutex_unlock(&ipath_mutex);
315
* ipath_diagpkt_write - write an IB packet
316
* @fp: the diag data device file pointer
317
* @data: ipath_diag_pkt structure saying where to get the packet
318
* @count: size of data to write
319
* @off: unused by this code
321
static ssize_t ipath_diagpkt_write(struct file *fp,
322
const char __user *data,
323
size_t count, loff_t *off)
326
u32 plen, clen, pbufn;
327
struct ipath_diag_pkt odp;
328
struct ipath_diag_xpkt dp;
330
struct ipath_devdata *dd;
333
u32 l_state, lt_state; /* LinkState, LinkTrainingState */
335
if (count < sizeof(odp)) {
340
if (count == sizeof(dp)) {
341
if (copy_from_user(&dp, data, sizeof(dp))) {
345
} else if (copy_from_user(&odp, data, sizeof(odp))) {
351
* Due to padding/alignment issues (lessened with new struct)
352
* the old and new structs are the same length. We need to
353
* disambiguate them, which we can do because odp.len has never
354
* been less than the total of LRH+BTH+DETH so far, while
355
* dp.unit (same offset) unit is unlikely to get that high.
356
* Similarly, dp.data, the pointer to user at the same offset
357
* as odp.unit, is almost certainly at least one (512byte)page
358
* "above" NULL. The if-block below can be omitted if compatibility
359
* between a new driver and older diagnostic code is unimportant.
360
* compatibility the other direction (new diags, old driver) is
361
* handled in the diagnostic code, with a warning.
363
if (dp.unit >= 20 && dp.data < 512) {
364
/* very probable version mismatch. Fix it up */
365
memcpy(&odp, &dp, sizeof(odp));
366
/* We got a legacy dp, copy elements to dp */
370
dp.pbc_wd = 0; /* Indicate we need to compute PBC wd */
373
/* send count must be an exact number of dwords */
381
dd = ipath_lookup(dp.unit);
382
if (!dd || !(dd->ipath_flags & IPATH_PRESENT) ||
383
!dd->ipath_kregbase) {
384
ipath_cdbg(VERBOSE, "illegal unit %u for diag data send\n",
390
if (ipath_diag_inuse && !diag_set_link &&
391
!(dd->ipath_flags & IPATH_LINKACTIVE)) {
393
ipath_cdbg(VERBOSE, "Trying to set to set link active for "
395
ipath_set_linkstate(dd, IPATH_IB_LINKARM);
396
ipath_set_linkstate(dd, IPATH_IB_LINKACTIVE);
399
if (!(dd->ipath_flags & IPATH_INITTED)) {
400
/* no hardware, freeze, etc. */
401
ipath_cdbg(VERBOSE, "unit %u not usable\n", dd->ipath_unit);
406
* Want to skip check for l_state if using custom PBC,
407
* because we might be trying to force an SM packet out.
408
* first-cut, skip _all_ state checking in that case.
410
val = ipath_ib_state(dd, dd->ipath_lastibcstat);
411
lt_state = ipath_ib_linktrstate(dd, dd->ipath_lastibcstat);
412
l_state = ipath_ib_linkstate(dd, dd->ipath_lastibcstat);
413
if (!dp.pbc_wd && (lt_state != INFINIPATH_IBCS_LT_STATE_LINKUP ||
414
(val != dd->ib_init && val != dd->ib_arm &&
415
val != dd->ib_active))) {
416
ipath_cdbg(VERBOSE, "unit %u not ready (state %llx)\n",
417
dd->ipath_unit, (unsigned long long) val);
422
/* need total length before first word written */
423
/* +1 word is for the qword padding */
424
plen = sizeof(u32) + dp.len;
426
if ((plen + 4) > dd->ipath_ibmaxlen) {
427
ipath_dbg("Pkt len 0x%x > ibmaxlen %x\n",
428
plen - 4, dd->ipath_ibmaxlen);
430
goto bail; /* before writing pbc */
432
tmpbuf = vmalloc(plen);
434
dev_info(&dd->pcidev->dev, "Unable to allocate tmp buffer, "
440
if (copy_from_user(tmpbuf,
441
(const void __user *) (unsigned long) dp.data,
447
plen >>= 2; /* in dwords */
449
piobuf = ipath_getpiobuf(dd, plen, &pbufn);
451
ipath_cdbg(VERBOSE, "No PIO buffers avail unit for %u\n",
456
/* disarm it just to be extra sure */
457
ipath_disarm_piobufs(dd, pbufn, 1);
459
if (ipath_debug & __IPATH_PKTDBG)
460
ipath_cdbg(VERBOSE, "unit %u 0x%x+1w pio%d\n",
461
dd->ipath_unit, plen - 1, pbufn);
465
writeq(dp.pbc_wd, piobuf);
467
* Copy all by the trigger word, then flush, so it's written
468
* to chip before trigger word, then write trigger word, then
469
* flush again, so packet is sent.
471
if (dd->ipath_flags & IPATH_PIO_FLUSH_WC) {
473
__iowrite32_copy(piobuf + 2, tmpbuf, clen - 1);
475
__raw_writel(tmpbuf[clen - 1], piobuf + clen + 1);
477
__iowrite32_copy(piobuf + 2, tmpbuf, clen);
488
static int ipath_diag_release(struct inode *in, struct file *fp)
490
mutex_lock(&ipath_mutex);
491
ipath_diag_inuse = 0;
492
fp->private_data = NULL;
493
mutex_unlock(&ipath_mutex);
497
static ssize_t ipath_diag_read(struct file *fp, char __user *data,
498
size_t count, loff_t *off)
500
struct ipath_devdata *dd = fp->private_data;
501
void __iomem *kreg_base;
504
kreg_base = dd->ipath_kregbase;
508
else if ((count % 4) || (*off % 4))
509
/* address or length is not 32-bit aligned, hence invalid */
511
else if (ipath_diag_inuse < 1 && (*off || count != 8))
512
ret = -EINVAL; /* prevent cat /dev/ipath_diag* */
513
else if ((count % 8) || (*off % 8))
514
/* address or length not 64-bit aligned; do 32-bit reads */
515
ret = ipath_read_umem32(dd, data, kreg_base + *off, count);
517
ret = ipath_read_umem64(dd, data, kreg_base + *off, count);
522
if (ipath_diag_inuse == -2)
529
static ssize_t ipath_diag_write(struct file *fp, const char __user *data,
530
size_t count, loff_t *off)
532
struct ipath_devdata *dd = fp->private_data;
533
void __iomem *kreg_base;
536
kreg_base = dd->ipath_kregbase;
540
else if ((count % 4) || (*off % 4))
541
/* address or length is not 32-bit aligned, hence invalid */
543
else if ((ipath_diag_inuse == -1 && (*off || count != 8)) ||
544
ipath_diag_inuse == -2) /* read qw off 0, write qw off 0 */
545
ret = -EINVAL; /* before any other write allowed */
546
else if ((count % 8) || (*off % 8))
547
/* address or length not 64-bit aligned; do 32-bit writes */
548
ret = ipath_write_umem32(dd, kreg_base + *off, data, count);
550
ret = ipath_write_umem64(dd, kreg_base + *off, data, count);
555
if (ipath_diag_inuse == -1)
556
ipath_diag_inuse = 1; /* all read/write OK now */