1.\" 2.\" Copyright (c) 1998 Kenneth D. Merry. 3.\" All rights reserved. 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 1. Redistributions of source code must retain the above copyright 9.\" notice, this list of conditions and the following disclaimer. 10.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" notice, this list of conditions and the following disclaimer in the 12.\" documentation and/or other materials provided with the distribution. 13.\" 3. The name of the author may not be used to endorse or promote products 14.\" derived from this software without specific prior written permission. 15.\" 16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26.\" SUCH DAMAGE. 27.\" 28.\" $FreeBSD$ 29.\" 30.Dd June 1, 2023 31.Dt CAM 3 32.Os 33.Sh NAME 34.Nm cam_open_device , 35.Nm cam_open_spec_device , 36.Nm cam_open_btl , 37.Nm cam_open_pass , 38.Nm cam_close_device , 39.Nm cam_close_spec_device , 40.Nm cam_getccb , 41.Nm cam_send_ccb , 42.Nm cam_freeccb , 43.Nm cam_path_string , 44.Nm cam_device_dup , 45.Nm cam_device_copy , 46.Nm cam_get_device 47.Nd CAM user library 48.Sh LIBRARY 49.Lb libcam 50.Sh SYNOPSIS 51.In stdio.h 52.In camlib.h 53.Ft struct cam_device * 54.Fo cam_open_device 55.Fa "const char *path" 56.Fa "int flags" 57.Fc 58.Ft struct cam_device * 59.Fo cam_open_spec_device 60.Fa "const char *dev_name" 61.Fa "int unit" 62.Fa "int flags" 63.Fa "struct cam_device *device" 64.Fc 65.Ft struct cam_device * 66.Fo cam_open_btl 67.Fa "path_id_t path_id" 68.Fa "target_id_t target_id" 69.Fa "lun_id_t target_lun" 70.Fa "int flags" 71.Fa "struct cam_device *device" 72.Fc 73.Ft struct cam_device * 74.Fo cam_open_pass 75.Fa "const char *path" 76.Fa "int flags" 77.Fa "struct cam_device *device" 78.Fc 79.Ft void 80.Fo cam_close_device 81.Fa "struct cam_device *dev" 82.Fc 83.Ft void 84.Fo cam_close_spec_device 85.Fa "struct cam_device *dev" 86.Fc 87.Ft union ccb * 88.Fo cam_getccb 89.Fa "struct cam_device *dev" 90.Fc 91.Ft int 92.Fo cam_send_ccb 93.Fa "struct cam_device *device" 94.Fa "union ccb *ccb" 95.Fc 96.Ft void 97.Fo cam_freeccb 98.Fa "union ccb *ccb" 99.Fc 100.Ft char * 101.Fo cam_path_string 102.Fa "struct cam_device *dev" 103.Fa "char *str" 104.Fa "int len" 105.Fc 106.Ft struct cam_device * 107.Fo cam_device_dup 108.Fa "struct cam_device *device" 109.Fc 110.Ft void 111.Fo cam_device_copy 112.Fa "struct cam_device *src" 113.Fa "struct cam_device *dst" 114.Fc 115.Ft int 116.Fo cam_get_device 117.Fa "const char *path" 118.Fa "char *dev_name" 119.Fa "int devnamelen" 120.Fa "int *unit" 121.Fc 122.Sh DESCRIPTION 123The CAM library consists of a number of functions designed to aid in 124programming with the CAM subsystem described in 125.Xr cam 4 . 126This man page covers the basic set of 127library functions. 128More functions are documented in the man pages listed 129below. 130.Pp 131Many of the CAM library functions use the 132.Va cam_device 133structure: 134.Bd -literal 135struct cam_device { 136 char device_path[MAXPATHLEN+1];/* 137 * Pathname of the 138 * device given by the 139 * user. This may be 140 * null if the user 141 * states the device 142 * name and unit number 143 * separately. 144 */ 145 char given_dev_name[DEV_IDLEN+1];/* 146 * Device name given by 147 * the user. 148 */ 149 uint32_t given_unit_number; /* 150 * Unit number given by 151 * the user. 152 */ 153 char device_name[DEV_IDLEN+1];/* 154 * Name of the device, 155 * e.g., 'pass' 156 */ 157 uint32_t dev_unit_num; /* Unit number of the passthrough 158 * device associated with this 159 * particular device. 160 */ 161 162 char sim_name[SIM_IDLEN+1];/* 163 * Controller name, e.g., 'ahc' 164 */ 165 uint32_t sim_unit_number; /* Controller unit number */ 166 uint32_t bus_id; /* Controller bus number */ 167 lun_id_t target_lun; /* Logical Unit Number */ 168 target_id_t target_id; /* Target ID */ 169 path_id_t path_id; /* System SCSI bus number */ 170 uint16_t pd_type; /* type of peripheral device */ 171 struct scsi_inquiry_data inq_data; /* SCSI Inquiry data */ 172 uint8_t serial_num[252]; /* device serial number */ 173 uint8_t serial_num_len; /* length of the serial number */ 174 uint8_t sync_period; /* Negotiated sync period */ 175 uint8_t sync_offset; /* Negotiated sync offset */ 176 uint8_t bus_width; /* Negotiated bus width */ 177 int fd; /* file descriptor for device */ 178}; 179.Ed 180.Pp 181.Fn cam_open_device 182takes as arguments a string describing the device it is to open, and 183.Ar flags 184suitable for passing to 185.Xr open 2 . 186The "path" passed in may actually be most any type of string that contains 187a device name and unit number to be opened. 188The string will be parsed by 189.Fn cam_get_device 190into a device name and unit number. 191Once the device name and unit number 192are determined, a lookup is performed to determine the passthrough device 193that corresponds to the given device. 194.Pp 195.Fn cam_open_spec_device 196opens the 197.Xr pass 4 198device that corresponds to the device name and unit number passed in. 199The 200.Ar flags 201should be flags suitable for passing to 202.Xr open 2 . 203The 204.Ar device 205argument is optional. 206The user may supply pre-allocated space for the 207.Va cam_device 208structure. 209If the 210.Ar device 211argument is 212.Dv NULL , 213.Fn cam_open_spec_device 214will allocate space for the 215.Va cam_device 216structure using 217.Xr malloc 3 . 218.Pp 219.Fn cam_open_btl 220is similar to 221.Fn cam_open_spec_device , 222except that it takes a SCSI bus, 223target and logical unit instead of a device name and unit number as 224arguments. 225The 226.Va path_id 227argument is the CAM equivalent of a SCSI bus number. 228It represents the logical bus number in the system. 229The 230.Ar flags 231should be flags suitable for passing to 232.Xr open 2 . 233As with 234.Fn cam_open_spec_device , 235the 236.Fa device 237argument is optional. 238.Pp 239.Fn cam_open_pass 240takes as an argument the 241.Fa path 242of a 243.Xr pass 4 244device to open. 245No translation or lookup is performed, so the path passed 246in must be that of a CAM 247.Xr pass 4 248device. 249The 250.Fa flags 251should be flags suitable for passing to 252.Xr open 2 . 253The 254.Fa device 255argument, as with 256.Fn cam_open_spec_device 257and 258.Fn cam_open_btl , 259should be 260.Dv NULL 261if the user wants the CAM library to allocate space for the 262.Va cam_device 263structure. 264.Pp 265.Fn cam_close_device 266frees the 267.Va cam_device 268structure allocated by one of the above 269.Xr open 2 270calls, and closes the file 271descriptor to the passthrough device. 272This routine should not be called if 273the user allocated space for the 274.Va cam_device 275structure. 276Instead, the user should call 277.Fn cam_close_spec_device . 278.Pp 279.Fn cam_close_spec_device 280merely closes the file descriptor opened in one of the 281.Xr open 2 282routines 283described above. 284This function should be called when the 285.Va cam_device 286structure was allocated by the caller, rather than the CAM library. 287.Pp 288.Fn cam_getccb 289allocates a prezeroed CCB 290using 291.Xr calloc 3 292and sets fields in the CCB header using values from the 293.Va cam_device 294structure. 295.Pp 296.Fn cam_send_ccb 297sends the given 298.Va ccb 299to the 300.Fa device 301described in the 302.Va cam_device 303structure. 304.Pp 305.Fn cam_freeccb 306frees CCBs allocated by 307.Fn cam_getccb . 308If 309.Va ccb 310is 311.Dv NULL , 312no action is taken. 313.Pp 314.Fn cam_path_string 315takes as arguments a 316.Va cam_device 317structure, and a string with length 318.Fa len . 319It creates a colon-terminated printing prefix string similar to the ones 320used by the kernel. 321e.g.: "(cd0:ahc1:0:4:0): ". 322.Fn cam_path_string 323will place at most 324.Fa len Ns \-1 325characters into 326.Ar str . 327The 328.Ar len Ns 'th 329character will be the terminating 330.Ql \e0 . 331.Pp 332.Fn cam_device_dup 333operates in a fashion similar to 334.Xr strdup 3 . 335It allocates space for a 336.Va cam_device 337structure and copies the contents of the passed-in 338.Fa device 339structure to the newly allocated structure. 340.Pp 341.Fn cam_device_copy 342copies the 343.Fa src 344structure to 345.Fa dst . 346.Pp 347.Fn cam_get_device 348takes a 349.Fa path 350argument containing a string with a device name followed by a unit number. 351It then breaks the string down into a device name and unit number, and 352passes them back in 353.Fa dev_name 354and 355.Fa unit , 356respectively. 357.Fn cam_get_device 358can handle strings of the following forms, at least: 359.Pp 360.Bl -tag -width 1234 -compact 361.It /dev/foo1 362.It foo0 363.It nsa2 364.El 365.Pp 366.Fn cam_get_device 367is provided as a convenience function for applications that need to provide 368functionality similar to 369.Fn cam_open_device . 370.Sh RETURN VALUES 371.Fn cam_open_device , 372.Fn cam_open_spec_device , 373.Fn cam_open_btl , 374and 375.Fn cam_open_pass 376return a pointer to a 377.Va cam_device 378structure, or 379.Dv NULL 380if there was an error. 381.Pp 382.Fn cam_getccb 383returns an allocated and partially initialized CCB, or 384.Dv NULL 385if allocation of the CCB failed. 386.Pp 387.Fn cam_send_ccb 388returns a value of -1 if an error occurred, and 389.Va errno 390is set to indicate the error. 391.Pp 392.Fn cam_path_string 393returns a filled printing prefix string as a convenience. 394This is the same 395.Fa str 396that is passed into 397.Fn cam_path_string . 398.Pp 399.Fn cam_device_dup 400returns a copy of the 401.Va device 402passed in, or 403.Dv NULL 404if an error occurred. 405.Pp 406.Fn cam_get_device 407returns 0 for success, and -1 to indicate failure. 408.Pp 409If an error is returned from one of the base CAM library functions 410described here, the reason for the error is generally printed in the global 411string 412.Va cam_errbuf 413which is 414.Dv CAM_ERRBUF_SIZE 415characters long. 416.Sh SEE ALSO 417.Xr cam_cdbparse 3 , 418.Xr pass 4 , 419.Xr camcontrol 8 420.Sh HISTORY 421The CAM library first appeared in 422.Fx 3.0 . 423.Sh AUTHORS 424.An Kenneth Merry Aq Mt ken@FreeBSD.org 425.Sh BUGS 426.Fn cam_open_device 427does not check to see if the 428.Fa path 429passed in is a symlink to something. 430It also does not check to see if the 431.Fa path 432passed in is an actual 433.Xr pass 4 434device. 435The former would be rather easy to implement, but the latter would 436require a definitive way to identify a device node as a 437.Xr pass 4 438device. 439.Pp 440Some of the functions are possibly misnamed or poorly named. 441