Skip site navigation (1)Skip section navigation (2)


| raw e-mail | index | archive | help
Also, bnxtnvm and niccli don't work with the driver in my kernel.  But it
isn't, apparently, because of the state of the driver, it is because of the
ioctl definition in the driver.  The ioctl call doesn't even get to
bnxt_mgmt_ioctl.  I've verified that with dtrace, but here is the ioctl call
from ktrace/kdump:

  7818 bnxtnvm  CALL  openat(AT_FDCWD,0x46199d,0x2<O_RDWR>)
  7818 bnxtnvm  NAMI  "/dev/bnxt_mgmt"
  7818 bnxtnvm  RET   openat 4
  7818 bnxtnvm  CALL  ioctl(0x4,0x80000000,0x821199a70)
  7818 bnxtnvm  RET   ioctl -1 errno 25 Inappropriate ioctl for device
  7818 bnxtnvm  CALL  close(0x4)

Using this Dtrace script:
#pragma D option cleanrate=3D5000hz
#pragma D option dynvarsize=3D8192000

fbt::bnxt_mgmt_ioctl:entry
{
        printf("cmd =3D %#x\n", args[1]);
}

fbt::bnxt_mgmt_open:entry
{
        printf("opened bnxt mgmt device\n");
}

fbt::sys_ioctl:entry
/args[1]->com =3D=3D 0x80000000/
{
        printf("got ioctl command 0x80000000\n");
}

I verified that it isn't getting down to bnxt_mgmt_ioctl:

# dtrace -s bnxt.d=20
dtrace: script 'bnxt.d' matched 3 probes
CPU     ID                    FUNCTION:NAME
 31   2108             bnxt_mgmt_open:entry opened bnxt mgmt device

 31  22882                  sys_ioctl:entry got ioctl command 0x80000000

 31   2108             bnxt_mgmt_open:entry opened bnxt mgmt device

 31  22882                  sys_ioctl:entry got ioctl command 0x80000000

^C

When I boot the machine via PXE, though, bnxtnvm listdev shows the device:

# ./bnxtnvm listdev

N/A #1
Device Interface Name       : bnxt0
MACAddress                  : 9c:6b:00:46:a2:0c
PCI Device Name             : 0000:c3:00.0

And strangely the ioctl works, although from my reading of sys_ioctl(), it
shouldn't but I think I've discovered why it does:

  1904 bnxtnvm  CALL  openat(AT_FDCWD,0x46199d,0x2<O_RDWR>)
  1904 bnxtnvm  NAMI  "/dev/bnxt_mgmt"
  1904 bnxtnvm  RET   openat 3
  1904 bnxtnvm  CALL  ioctl(0x3,0x80000000,0x8212303d0)
  1904 bnxtnvm  RET   ioctl 0
  1904 bnxtnvm  CALL  close(0x3)

This code is from sys_ioctl():


        /*
         * Interpret high order word to find amount of data to be
         * copied to/from the user's address space.
         */
        size =3D IOCPARM_LEN(com);
        if ((size > IOCPARM_MAX) ||
            ((com & (IOC_VOID  | IOC_IN | IOC_OUT)) =3D=3D 0) ||
#if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_=
43)
            ((com & IOC_OUT) && size =3D=3D 0) ||
#else
            ((com & (IOC_IN | IOC_OUT)) && size =3D=3D 0) ||
#endif
            ((com & IOC_VOID) && size > 0 && size !=3D sizeof(int)))
                return (ENOTTY);

My regular kernel config file doesn't have COMPAT_FREEBSD4/5, but the PXE
kernel config file does.

Here are the bit definitions from sys/ioccom.h:
#ifndef _SYS_IOCCOM_H_
#define _SYS_IOCCOM_H_

/*
 * Ioctl's have the command encoded in the lower word, and the size of
 * any in or out parameters in the upper word.  The high 3 bits of the
 * upper word are used to encode the in/out status of the parameter.
 *
 *       31 29 28                     16 15            8 7             0
 *      +---------------------------------------------------------------+
 *      | I/O | Parameter Length        | Command Group | Command       |
 *      +---------------------------------------------------------------+
 */
#define IOCPARM_SHIFT   13              /* number of bits for ioctl size */
#define IOCPARM_MASK    ((1 << IOCPARM_SHIFT) - 1) /* parameter length mask=
 */
#define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
#define IOCBASECMD(x)   ((x) & ~(IOCPARM_MASK << 16))
#define IOCGROUP(x)     (((x) >> 8) & 0xff)

#define IOCPARM_MAX     (1 << IOCPARM_SHIFT) /* max size of ioctl */

#define IOC_VOID        0x20000000UL    /* no parameters */
#define IOC_OUT         0x40000000UL    /* copy out parameters */
#define IOC_IN          0x80000000UL    /* copy in parameters */
#define IOC_INOUT       (IOC_IN|IOC_OUT)/* copy parameters in and out */
#define IOC_DIRMASK     (IOC_VOID|IOC_OUT|IOC_IN)/* mask for IN/OUT/VOID */

Because the BNXT_MGMT_OPCODE_GET_DEV_INFO ioctl the same as the IOC_IN bit
definition, the ioctl breaks if the old compat stuff isn't built into the
kernel.

The ioctls for the bnxt(4) driver need to be changed to use the usual
_IOW/_IOWR macros from sys/ioccom.h.  I realize that will break the managem=
ent
tools.  Perhaps they can have a version check and a fallback to the old ioc=
tls
if need be.

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?>