| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | USERSPACE MAD ACCESS | 
 | 2 |  | 
 | 3 | Device files | 
 | 4 |  | 
 | 5 |   Each port of each InfiniBand device has a "umad" device and an | 
 | 6 |   "issm" device attached.  For example, a two-port HCA will have two | 
 | 7 |   umad devices and two issm devices, while a switch will have one | 
 | 8 |   device of each type (for switch port 0). | 
 | 9 |  | 
 | 10 | Creating MAD agents | 
 | 11 |  | 
 | 12 |   A MAD agent can be created by filling in a struct ib_user_mad_reg_req | 
 | 13 |   and then calling the IB_USER_MAD_REGISTER_AGENT ioctl on a file | 
 | 14 |   descriptor for the appropriate device file.  If the registration | 
 | 15 |   request succeeds, a 32-bit id will be returned in the structure. | 
 | 16 |   For example: | 
 | 17 |  | 
 | 18 | 	struct ib_user_mad_reg_req req = { /* ... */ }; | 
 | 19 | 	ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req); | 
 | 20 |         if (!ret) | 
 | 21 | 		my_agent = req.id; | 
 | 22 | 	else | 
 | 23 | 		perror("agent register"); | 
 | 24 |  | 
 | 25 |   Agents can be unregistered with the IB_USER_MAD_UNREGISTER_AGENT | 
 | 26 |   ioctl.  Also, all agents registered through a file descriptor will | 
 | 27 |   be unregistered when the descriptor is closed. | 
 | 28 |  | 
 | 29 | Receiving MADs | 
 | 30 |  | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 31 |   MADs are received using read().  The receive side now supports | 
 | 32 |   RMPP. The buffer passed to read() must be at least one | 
 | 33 |   struct ib_user_mad + 256 bytes. For example: | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 34 |  | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 35 |   If the buffer passed is not large enough to hold the received | 
 | 36 |   MAD (RMPP), the errno is set to ENOSPC and the length of the | 
 | 37 |   buffer needed is set in mad.length. | 
 | 38 |  | 
 | 39 |   Example for normal MAD (non RMPP) reads: | 
 | 40 | 	struct ib_user_mad *mad; | 
 | 41 | 	mad = malloc(sizeof *mad + 256); | 
 | 42 | 	ret = read(fd, mad, sizeof *mad + 256); | 
 | 43 | 	if (ret != sizeof mad + 256) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | 		perror("read"); | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 45 | 		free(mad); | 
 | 46 | 	} | 
 | 47 |  | 
 | 48 |   Example for RMPP reads: | 
 | 49 | 	struct ib_user_mad *mad; | 
 | 50 | 	mad = malloc(sizeof *mad + 256); | 
 | 51 | 	ret = read(fd, mad, sizeof *mad + 256); | 
 | 52 | 	if (ret == -ENOSPC)) { | 
 | 53 | 		length = mad.length; | 
 | 54 | 		free(mad); | 
 | 55 | 		mad = malloc(sizeof *mad + length); | 
 | 56 | 		ret = read(fd, mad, sizeof *mad + length); | 
 | 57 | 	} | 
 | 58 | 	if (ret < 0) { | 
 | 59 | 		perror("read"); | 
 | 60 | 		free(mad); | 
 | 61 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 62 |  | 
 | 63 |   In addition to the actual MAD contents, the other struct ib_user_mad | 
 | 64 |   fields will be filled in with information on the received MAD.  For | 
 | 65 |   example, the remote LID will be in mad.lid. | 
 | 66 |  | 
 | 67 |   If a send times out, a receive will be generated with mad.status set | 
 | 68 |   to ETIMEDOUT.  Otherwise when a MAD has been successfully received, | 
 | 69 |   mad.status will be 0. | 
 | 70 |  | 
 | 71 |   poll()/select() may be used to wait until a MAD can be read. | 
 | 72 |  | 
 | 73 | Sending MADs | 
 | 74 |  | 
 | 75 |   MADs are sent using write().  The agent ID for sending should be | 
 | 76 |   filled into the id field of the MAD, the destination LID should be | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 77 |   filled into the lid field, and so on.  The send side does support | 
 | 78 |   RMPP so arbitrary length MAD can be sent. For example: | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 79 |  | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 80 | 	struct ib_user_mad *mad; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 81 |  | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 82 | 	mad = malloc(sizeof *mad + mad_length); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 83 |  | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 84 | 	/* fill in mad->data */ | 
 | 85 |  | 
 | 86 | 	mad->hdr.id  = my_agent;	/* req.id from agent registration */ | 
 | 87 | 	mad->hdr.lid = my_dest;		/* in network byte order... */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 | 	/* etc. */ | 
 | 89 |  | 
| Hal Rosenstock | 3f75dad | 2005-07-27 11:45:41 -0700 | [diff] [blame] | 90 | 	ret = write(fd, &mad, sizeof *mad + mad_length); | 
 | 91 | 	if (ret != sizeof *mad + mad_length) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 92 | 		perror("write"); | 
 | 93 |  | 
| Hal Rosenstock | bd8031b | 2007-04-24 21:30:38 -0700 | [diff] [blame^] | 94 | Transaction IDs | 
 | 95 |  | 
 | 96 |   Users of the umad devices can use the lower 32 bits of the | 
 | 97 |   transaction ID field (that is, the least significant half of the | 
 | 98 |   field in network byte order) in MADs being sent to match | 
 | 99 |   request/response pairs.  The upper 32 bits are reserved for use by | 
 | 100 |   the kernel and will be overwritten before a MAD is sent. | 
 | 101 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 102 | Setting IsSM Capability Bit | 
 | 103 |  | 
 | 104 |   To set the IsSM capability bit for a port, simply open the | 
 | 105 |   corresponding issm device file.  If the IsSM bit is already set, | 
 | 106 |   then the open call will block until the bit is cleared (or return | 
 | 107 |   immediately with errno set to EAGAIN if the O_NONBLOCK flag is | 
 | 108 |   passed to open()).  The IsSM bit will be cleared when the issm file | 
 | 109 |   is closed.  No read, write or other operations can be performed on | 
 | 110 |   the issm file. | 
 | 111 |  | 
 | 112 | /dev files | 
 | 113 |  | 
 | 114 |   To create the appropriate character device files automatically with | 
 | 115 |   udev, a rule like | 
 | 116 |  | 
 | 117 |     KERNEL="umad*", NAME="infiniband/%k" | 
 | 118 |     KERNEL="issm*", NAME="infiniband/%k" | 
 | 119 |  | 
 | 120 |   can be used.  This will create device nodes named | 
 | 121 |  | 
 | 122 |     /dev/infiniband/umad0 | 
 | 123 |     /dev/infiniband/issm0 | 
 | 124 |  | 
 | 125 |   for the first port, and so on.  The InfiniBand device and port | 
 | 126 |   associated with these devices can be determined from the files | 
 | 127 |  | 
 | 128 |     /sys/class/infiniband_mad/umad0/ibdev | 
 | 129 |     /sys/class/infiniband_mad/umad0/port | 
 | 130 |  | 
 | 131 |   and | 
 | 132 |  | 
 | 133 |     /sys/class/infiniband_mad/issm0/ibdev | 
 | 134 |     /sys/class/infiniband_mad/issm0/port |