Home   |  About Us   |  What's New   |  Products   |  Services   |  Support   |  Other Sites   |  Clients   |  Contact Us
ADS
Return to PCIHSD

Return to PCIHSD2

Return to CPCIHSD

Printable Version


1.4 - Requirements

2.1 - General Information

2.2 - PCIHSD Devices in Linux

2.3 - IBL Mode Support

2.4 - Symbol Definitions

2.5 - OPEN Function

2.6 - CLOSE Function

2.7 - READ Function

2.8 - WRITE Function

2.9 - Data Transfer Options

2.10 - IOCTL Function

2.10.1 - HSDGETMOD [Get PCIHSD Operating Mode]

2.10.2 - HSDSETMOD [Set PCIHSD Operating Mode]

2.10.3 - HSDRESET [Perform PCIHSD Reset Operations]

2.10.4 - HSDGETSTS [Read PCIHSD Board Status]

2.10.5 - HSDGETXSTS [Get Extended Driver Status]

3.1 - Introduction

3.2 - Reference Documents

3.3 - pcihsd_mode_t Structure

3.4 - pcihsd_sts_t Structure

4.1 - Status Returns

4.2 - Extended Status Returns

4.3 - PCIHSD Board Status Returns

5.1 - Distribution Media

5.2 - Installation

5.2.1 - Completing the Installation

5.2.2 - Installation Details

Example Programs


Applied Data Sciences / PCIHSD® Linux Driver

The PCIHSD driver, "PCIHSD", is intended for operation under Linux, version 2.2.x. The driver handles all communication with the PCIHSD on behalf of the calling program. It allows for reading and setting the operating mode of the PCIHSD. It provides synchronous (wait mode) data transfers via read(2) and write(2) calls. Device command and status request operations are performed by reads and writes at unique file offset addresses, operations that are easily performed using the pread(2) and pwrite(2) calls.

Details of the driver installation are in Section 5.0.

Note: The PCIHSD driver operates only in Linux kernel versions 2.2.x and later.

To download a printable version of this page, please click here.

To search the current page for information, please use the box below.  Search help.

2.2 - PCIHSD Devices in Linux:

Under Linux, a PCIHSD board is represented as character device accessed through a node found the /dev directory of the filesystem. The name of the node is used in the open(2) call to access the device. When the driver is loaded into the kernel, it allows the kernel to assign a major number for the nodes. The minor number for a node must be assigned to reflect the relative position of the board on the bus. The driver assumes the minor numbers start at zero and increment by one for each PCIHSD board in the system. When the driver is loaded, it searches for all the PCIHSD boards in the system and numbers them as they are found. The minor number is used by the driver to identify the desired PCIHSD board.

The following is a typical entry for a two, PCIHSD board system:

    /dev/pcihsd0 Character device with minor number of 0 for the first board.

    /dev/pcihsd1 Character device with minor number of 1 for the second board.

2.3 - IBL Mode Support:

The PCIHSD driver provides three protocols for initiating a link for data transfers in the InterBus Link (IBL) configuration. The desired mode is specified in the link field of a pcihsd_mode_t structure passed to an HSDSETMOD call. If PCIHM_LREQ is specified, the PCIHSD will initiate the link request for all transfers. If PCIHM_LACK is specified, the PCIHSD does not initiate any link request, but expects to wait for, and acknowledge a link request before each data transfer. A third option uses the protocol of the Encore H.IBLG handler under MPX and initiates the link request when the operation is a Write or waits for and acknowledges a link request when the operation is a Read. This method is specified by PCIHM_LIBLG in the link field or the pcihsd_mode_t structure.

2.7 - READ Function:

The standard read(2) function is used to transfer data from the PCIHSD to the user's buffer or to retrieve device status. Data transfers are buffered into kernel space before being moved to the user's buffer. The user's transfer byte count must be a multiple of four. The maximum length of a single transfer is 262,140 bytes (65535 or FFFF16 32-bit words). This is the maximum that can be transferred by a single IOCB. If the requested transfer size exceeds the maximum, the driver will return an error (EINVAL). The extended error code, which may be retrieved via an HSDGETXSTS call, will be EXLONG (transfer count too long).

The IOCB command word presented to the external device to initiate the data transfer contains 8-bits (bits 16-23) of user-device-dependent (UDD) information. Unless the PCIHM_NOUDD flag bit is set (see Section 2.9) the least-significant 8-bits of the current file position will be used as the UDD byte for the read IOCB. The pread(2) call is a convenient way to set the file position and transfer data, effectively combining calls to lseek(2) and read(2). The UDDBYTE macro, defined in pcihsdio.h, is useful in conjunction with these calls, for example:

nread = pread (fd, &buffer, bfrlen, UDDBYTE(0x20));

An external device status request may be performed by issuing a read(2) or pread(2) call with the file position set to the hexadecimal value 20xxxxxx (where the x's are arbitrary values). The file position is used as the IOCB command word for the request and the external device status word (4 bytes only) is returned to the user's buffer. The R_DSR macro defined in pcihsdio.h generates the required file position word:

uint devstat;

status = pread(fd, &devstat, 4, R_DSR(0x440000));

This call will issue a device status request with 4416 in the UDD byte, returning the status word to devstat.

In addition to the errors, which may normally be returned from the read call, the following additional conditions may be reported by errno values:

EINVAL Requested transfer length is greater than the maximum allowed or is not a multiple of four bytes (1 longword).

EIO An error occurred in the data transfer.

Further explanation may be obtained by issuing the ioctl(HSDGETXSTS) call and examining the returned value. (See Section 2.10.5.)

2.8 - WRITE Function:

The standard write(2) function is used to transfer data from the user's buffer to the PCIHSD or to send device commands. Both device command transfers and data transfers are buffered through the driver. The user's transfer byte count must be a multiple of four for data transfers. Device command transfers must be a multiple of 8 bytes long. The maximum length of a single transfer is 262,140 bytes (65535 or FFFF16 32-bit words). This is the maximum that can be transferred by a single IOCB. If the requested transfer size exceeds the maximum, the driver will return an error (EINVAL). The extended error code, which may be retrieved via an HSDGETXSTS call, will be EXLONG (transfer count too long).

The IOCB command word presented to the external device to initiate the data transfer contains 8-bits (bits 16-23) of user-device-dependent (UDD) information. Unless the PCIHM_NOUDD flag bit is set (see Section 2.9) the least-significant 8-bits of the current file position will be used as the UDD byte for the read IOCB. The pwrite(2) call is a convenient way to set the file position and transfer data, effectively combining calls to lseek(2) and write(2). The UDDBYTE macro, defined in pcihsdio.h, is useful in conjunction with these calls, for example:

nwrt = pwrite (fd, &buffer, bfrlen, UDDBYTE(0x20));

One or more commands may be sent to the external device by issuing a write(2) or pwrite(2) call with the file position set to the hexadecimal value 40xxxxxx (where the x's are arbitrary values) and the transfer count a multiple of 8 bytes. Each successive 8 bytes (2 HSD words) from the user's buffer are sent to the PCIHSD as the two IOCB words of a device command. The W_CMD macro defined in pcihsdio.h generates the required file position word:

uint devcmd[2]={0x40010002, 0x12345678};

status = pwrite(fd, devcmd, 8, W_CMD);

This call will send the device command contained in the devcmd array.

In addition to the errors, which may normally be returned from the write(2) call, the following additional conditions may be reported by errno values:

EINVAL Requested transfer length is greater than the maximum allowable or is not a multiple of four bytes (1 longword).

EIO An error occurred in the data transfer.

Further explanation may be obtained by issuing the ioctl(HSDGETXSTS) call and examining the returned value. (See Section 2.10.5.)

2.10 - IOCTL Function:

The ioctl(2) call is used to read PCIHSD status and perform reset operations. The ioctl call requires the user to pass the file descriptor of an open device file, a function code and an argument. All ioctl calls are performed synchronously. That is, the operation is completed and any status information to be returned to the caller is stored before control returns from the ioctl call.

Any of these functions may return a value of -1, with the variable errno set to one of the following error codes:

  • EFAULT If some part of a data structure passed as an argument is not accessible to the user.
  • EINVAL If some field in a data structure passed as an argument, is invalid or inappropriate.
  • ENXIO If the requested operation is illogical or impossible.
  • EIO If some I/O error occurred on the PCIHSD.
  • EBUSY If active I/O precludes performing the current request.
  • EPERM If the caller does not have the requisite privilege for the requested operation.
  • EINTR If a signal was caught during the course of the current function call.

Each subsection below discusses one of the ioctl functions and describes the required argument(s). Detailed information about the various data structures may be found in Section 3.0.

2.10.3 - HSDRESET [Perform PCIHSD Reset Operations]:

Argument: reset mode selection

This call performs the requested reset operation(s) on the addressed PCIHSD. The argument to this function is a reset mode selection which may be one of the following (defined in pcihsdio.h):

  • HSD_RS_HSD Reset HSD controller
  • HSD_RS_FIFO Reset FIFO's
  • HSD_RS_BOTH Reset FIFO's and HSD controller
  • HSD_RS_DVC Reset external device (IOReset)
  • HSD_RS_GEN General reset (HSD/FIFO/External Device)
  • HSD_RS_TDV Terminate Device (External Terminate)
  • HSD_RS_HALT Do HALTIO (stop any active DMA) only
  • HSD_RS_PCI Reset PCI bus interface chip
  • HSD_RS_LINK Reset "IBL Link Request Received" flag (see Section 5.2 for more information)

Unless the argument is HSD_RS_HALT, there must be no currently active I/O operation on the device.


3.3 - pcihsd_mode_t Structure:

The pcihsd_mode_t structure is used with the HSDGETMODE and HSDSETMODE calls to retrieve or change the PCIHSD's operating mode. This structure contains the following items:

opmode

  • Board operating mode code containing one of the following values defined in pcihsdio.h:
  • PCIHM_HSD operating as HSD
  • PCIHM_IBL operating as IBL

conn

  • Board connector configuration code containing one of the following values defined in pcihsdio.h:
  • PCIHM_CNRM Normal (HSD) connectors
  • PCIHM_CREV Reverse (IBL) connectors

Note: on an IBL link, certain signals must be transposed from one HSD device to the other. This is accomplished by either 1) using a cable with the appropriate wires interchanged and normal connectors on both HSD's or 2) using a straight-through cable and setting one of the HSD devices in a Reverse connector configuration.

link

  • IBL link request mode containing a code specifying the desired IBL link protocol and a single-bit field specifying the hardware link priority desired.
  • PCIHM_LREQ Always request IBL link when initiating a transfer.
  • PCIHM_LACK Never request IBL link when initiating transfer.
  • PCIHM_LIBLG Use link protocol of the Encore H.IBLG handler for MPX. (Request link if writing, don't request if reading.)
  • PCIHM_HIPRI Set high link priority. This bit may be or'd with any of the preceding values.

flags

  • Flag bits specifying options:
  • PCIHM_HZTO Interpret timeout values as clock ticks instead of seconds.
  • PCIHM_NOUDD Do not use file position as UDD byte on read/write calls.
  • PCIHM_CONTIBL ("Continuous IBL Mode", used with PCIHM_LACK) Wait for link request only on first read/write call.
  • PCIHM_NOLINK (Used with PCIHM_LACK) Do not wait for IBL link request before starting data transfer on read/write calls.

timeout

  • Timeout for data transfer operations. The value is normally interpreted as a number of seconds. If PCIHM_HZTO flag bit is set in flags, then timeout is interpreted as a number of clock ticks (HZ per second).


4.2 - Extended Status Returns:

The value returned by the HSDGETXSTS call contains two fields, a system error code (errno value) and an extended error code, which can be extracted by the HSDsyserr and HSDexterr macros, respectively. If the system error code is EINVAL or EIO, the extended codes give the following additional information:

Expansion of EINVAL code:

EXCMD: Buffer containing device commands is too long for one write operation or length is not a multiple of 8.

EXCNT: Transfer count on read or write is 0 or is not a multiple of 4.

EXMAPERR: Driver was unable to map user's buffer for DMA (should not occur).

EXLONG: Data transfer request is too long (more than 65535 32-bit words).

EXOOPS: Internal driver error building DMA descriptors for PCIHSD. Should not happen.

EXSTS: Buffer for a device status request is too short (must be at least 4 bytes).

EXMODE: The opmode field of the pcihsd_mode_t structure passed to an ioctl (SETMODE) call is invalid.

EXCONN: The conn field of the pcihsd_mode_t structure passed to an ioctl (SETMODE) call is invalid.

EXLINK: The link field of the pcihsd_mode_t structure passed to an ioctl (SETMODE) call is invalid.

Expansion of EIO code:

EXTIMO: Request not completed before timeout occurred.

EXTDV: I/O was terminated by External Terminate signal.

The following code may be returned with a system error code of 0 (all OK) if the HSDGETXSTS call immediately follows the open(2) on the device.

EXNODEV: No external device is connected.


5.2 - Installation:

Log onto Linux as root.

Create a subdirectory for the PCIHSD driver (if one is not already available). Any suitable directory can be used.

mkdir pcihsd

Change to the pcihsd directory.

cd pcihsd

Copy the installation files from the distribution floppy to the pcihsd directory:

mcopy -tm a:* .

The following files should be placed in the pcihsd directory for compiling the driver:

  • pcihsdrv.h: PCIHSD device table structure and other internal driver definitions.
  • pcihsdev.h: PCIHSD hardware definitions.
  • pcihsd.c: PCIHSD driver source.
  • pcihsdio.h: Structure and symbol definitions for users of PCIHSD driver. This file should also be placed in a suitable location for access by programs compiled to use the PCIHSD driver.
  • Makefile: Instructions for building driver.
  • ldpcihsd: Script file to dynamically install the pcihsd driver as a module in the Linux kernel and create nodes in /dev for accessing the PCIHSD devices.
  • u: Script file to unload the PCIHSD driver from the Linux kernel.
  • hsdexample.c: Example program using the PCIHSD driver in HSD mode.
  • iblexample.c: Example program using the PCIHSD driver in IBL mode.

Since the PCIHSD driver files are distributed in a DOS compatible form, it may be necessary to set the files' proper permissions. All distributed files should have read/write capabilities for user, group, and other. Use the following command to set these permissions.

chmod a+rw *

Additionally, the two script files must have execution permission. Set this permission using the following command.

chmod a+x ldpcihsd u

5.2.1 - Completing the Installation:

Compile the PCIHSD driver for the current Linux version by typing:

make

The module file, pcihsd.o, is created from the pcihsd.c, pcihsdev.h, pcihsdrv.h, and pcihsdio.h source files and is suitable for dynamically loading into the Linux kernel.

The PCIHSD driver is now available for loading into the Linux kernel. The script file, ldpcihsd, can be used to accomplish this task. The script file takes one parameter that specifies the number of PCIHSD boards in the system. The script file will create nodes in the /dev directory to access the boards. The PCIHSD driver lets Linux assign the major device number. The script file will determine the major number from the system and create the nodes with this major number. To load the driver and create the device nodes, type the following command:

./ldpcihsd n

where 'n' is the number of boards in the system.

5.2.2 - Installation Details:

The following symbols control the compilation of options within PCIHSD:

DEBUG: If this symbol is defined as n, debug tracing is enabled in the driver with the trace level initially set to n. A trace level of 0 suppresses trace output; higher levels increase the amount of trace output.

REV_LT_D: If this symbol is defined, code will be compiled to handle a status read problem with boards prior to Revision D. This symbol should be defined unless it is known that no pre-revision D boards will ever be used with this installation of the driver.

HOLD_LREQ: If this symbol is defined, the driver will not clear its "link request received" flag at the time of an open(2) call. This should be enabled in order to communicate via IBL link with a system that may come up and send a link request before the application is able to open the PCIHSD. The "link request received" flag can be cleared at any time by the HSD_RS_LINK reset option (see Section 2.10.3). If the PCIHM_LACK mode flag is set and the PCIHM_NOLINK option flag is not set, a link request must be received after this call completes before another data transfer can take place.

For additional information, please contact us at your convenience.  Copyright 2001 Applied Data Sciences, Inc. All rights reserved.