| 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: src/lib/libcam/cam.3,v 1.5.2.6 2001/12/17 10:08:28 ru Exp $ |
| 29 | .\" |
| 30 | .Dd October 10, 1998 |
| 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 |
| 123 | The CAM library consists of a number of functions designed to aid in |
| 124 | programming with the CAM subsystem. This man page covers the basic set of |
| 125 | library functions. More functions are documented in the man pages listed |
| 126 | below. |
| 127 | .Pp |
| 128 | Many of the CAM library functions use the |
| 129 | .Va cam_device |
| 130 | structure: |
| 131 | .Bd -literal |
| 132 | struct cam_device { |
| 133 | char device_path[MAXPATHLEN+1];/* |
| 134 | * Pathname of the |
| 135 | * device given by the |
| 136 | * user. This may be |
| 137 | * null if the user |
| 138 | * states the device |
| 139 | * name and unit number |
| 140 | * separately. |
| 141 | */ |
| 142 | char given_dev_name[DEV_IDLEN+1];/* |
| 143 | * Device name given by |
| 144 | * the user. |
| 145 | */ |
| 146 | u_int32_t given_unit_number; /* |
| 147 | * Unit number given by |
| 148 | * the user. |
| 149 | */ |
| 150 | char device_name[DEV_IDLEN+1];/* |
| 151 | * Name of the device, |
| 152 | * e.g. 'pass' |
| 153 | */ |
| 154 | u_int32_t dev_unit_num; /* Unit number of the passthrough |
| 155 | * device associated with this |
| 156 | * particular device. |
| 157 | */ |
| 158 | |
| 159 | char sim_name[SIM_IDLEN+1];/* |
| 160 | * Controller name, e.g.'ahc' |
| 161 | */ |
| 162 | u_int32_t sim_unit_number; /* Controller unit number */ |
| 163 | u_int32_t bus_id; /* Controller bus number */ |
| 164 | lun_id_t target_lun; /* Logical Unit Number */ |
| 165 | target_id_t target_id; /* Target ID */ |
| 166 | path_id_t path_id; /* System SCSI bus number */ |
| 167 | u_int16_t pd_type; /* type of peripheral device */ |
| 168 | struct scsi_inquiry_data inq_data; /* SCSI Inquiry data */ |
| 169 | u_int8_t serial_num[252]; /* device serial number */ |
| 170 | u_int8_t serial_num_len; /* length of the serial number */ |
| 171 | u_int8_t sync_period; /* Negotiated sync period */ |
| 172 | u_int8_t sync_offset; /* Negotiated sync offset */ |
| 173 | u_int8_t bus_width; /* Negotiated bus width */ |
| 174 | int fd; /* file descriptor for device */ |
| 175 | }; |
| 176 | .Ed |
| 177 | .Pp |
| 178 | .Fn cam_open_device |
| 179 | takes as arguments a string describing the device it is to open, and |
| 180 | .Ar flags |
| 181 | suitable for passing to |
| 182 | .Xr open 2 . |
| 183 | The "path" passed in may actually be most any type of string that contains |
| 184 | a device name and unit number to be opened. The string will be parsed by |
| 185 | .Fn cam_get_device |
| 186 | into a device name and unit number. Once the device name and unit number |
| 187 | are determined, a lookup is performed to determine the passthrough device |
| 188 | that corresponds to the given device. |
| 189 | .Fn cam_open_device |
| 190 | is rather simple to use, but it isn't really suitable for general use |
| 191 | because its behavior isn't necessarily deterministic. Programmers writing |
| 192 | new applications should make the extra effort to use one of the other open |
| 193 | routines documented below. |
| 194 | .Pp |
| 195 | .Fn cam_open_spec_device |
| 196 | opens the |
| 197 | .Xr pass 4 |
| 198 | device that corresponds to the device name and unit number passed in. The |
| 199 | .Ar flags |
| 200 | should be flags suitable for passing to |
| 201 | .Xr open 2 . |
| 202 | The |
| 203 | .Ar device |
| 204 | argument is optional. The user may supply pre-allocated space for the |
| 205 | .Va cam_device |
| 206 | structure. If the |
| 207 | .Ar device |
| 208 | argument is |
| 209 | .Va NULL , |
| 210 | .Fn cam_open_spec_device |
| 211 | will allocate space for the |
| 212 | .Va cam_device |
| 213 | structure using |
| 214 | .Xr malloc 3 . |
| 215 | .Pp |
| 216 | .Fn cam_open_btl |
| 217 | is similar to |
| 218 | .Fn cam_open_spec_device , |
| 219 | except that it takes a |
| 220 | .Tn SCSI |
| 221 | bus, target and logical unit instead of a device name and unit number as |
| 222 | arguments. The |
| 223 | .Va path_id |
| 224 | argument is the CAM equivalent of a |
| 225 | .Tn SCSI |
| 226 | bus number. It represents the logical bus number in the system. The |
| 227 | .Ar flags |
| 228 | should be flags suitable for passing to |
| 229 | .Xr open 2 . |
| 230 | As with |
| 231 | .Fn cam_open_spec_device , |
| 232 | the |
| 233 | .Fa device |
| 234 | argument is optional. |
| 235 | .Pp |
| 236 | .Fn cam_open_pass |
| 237 | takes as an argument the |
| 238 | .Fa path |
| 239 | of a |
| 240 | .Xr pass 4 |
| 241 | device to open. No translation or lookup is performed, so the path passed |
| 242 | in must be that of a CAM |
| 243 | .Xr pass 4 |
| 244 | device. The |
| 245 | .Fa flags |
| 246 | should be flags suitable for passing to |
| 247 | .Xr open 2 . |
| 248 | The |
| 249 | .Fa device |
| 250 | argument, as with |
| 251 | .Fn cam_open_spec_device |
| 252 | and |
| 253 | .Fn cam_open_btl , |
| 254 | should be NULL if the user wants the CAM library to allocate space for the |
| 255 | .Va cam_device |
| 256 | structure. |
| 257 | .Fn cam_close_device |
| 258 | frees the |
| 259 | .Va cam_device |
| 260 | structure allocated by one of the above open() calls, and closes the file |
| 261 | descriptor to the passthrough device. This routine should not be called if |
| 262 | the user allocated space for the |
| 263 | .Va cam_device |
| 264 | structure. Instead, the user should call |
| 265 | .Fn cam_close_spec_device . |
| 266 | .Pp |
| 267 | .Fn cam_close_spec_device |
| 268 | merely closes the file descriptor opened in one of the open() routines |
| 269 | described above. This function should be called when the |
| 270 | .Va cam_device |
| 271 | structure was allocated by the caller, rather than the CAM library. |
| 272 | .Pp |
| 273 | .Fn cam_getccb |
| 274 | allocates a CCB |
| 275 | using |
| 276 | .Xr malloc 3 |
| 277 | and sets fields in the CCB header using values from the |
| 278 | .Va cam_device |
| 279 | structure. |
| 280 | .Pp |
| 281 | .Fn cam_send_ccb |
| 282 | sends the given |
| 283 | .Va ccb |
| 284 | to the |
| 285 | .Fa device |
| 286 | described in the |
| 287 | .Va cam_device |
| 288 | structure. |
| 289 | .Pp |
| 290 | .Fn cam_freeccb |
| 291 | frees CCBs allocated by |
| 292 | .Fn cam_getccb . |
| 293 | .Pp |
| 294 | .Fn cam_path_string |
| 295 | takes as arguments a |
| 296 | .Va cam_device |
| 297 | structure, and a string with length |
| 298 | .Fa len . |
| 299 | It creates a colon-terminated printing prefix string similar to the ones |
| 300 | used by the kernel. e.g.: "(cd0:ahc1:0:4:0): ". |
| 301 | .Fn cam_path_string |
| 302 | will place at most |
| 303 | .Fa len Ns \-1 |
| 304 | characters into |
| 305 | .Ar str . |
| 306 | The |
| 307 | .Ar len Ns 'th |
| 308 | character will be the terminating |
| 309 | .Ql \e0 . |
| 310 | .Pp |
| 311 | .Fn cam_device_dup |
| 312 | operates in a fashion similar to |
| 313 | .Xr strdup 3 . |
| 314 | It allocates space for a |
| 315 | .Va cam_device |
| 316 | structure and copies the contents of the passed-in |
| 317 | .Fa device |
| 318 | structure to the newly allocated structure. |
| 319 | .Pp |
| 320 | .Fn cam_device_copy |
| 321 | copies the |
| 322 | .Fa src |
| 323 | structure to |
| 324 | .Fa dst . |
| 325 | .Pp |
| 326 | .Fn cam_get_device |
| 327 | takes a |
| 328 | .Fa path |
| 329 | argument containing a string with a device name followed by a unit number. |
| 330 | It then breaks the string down into a device name and unit number, and |
| 331 | passes them back in |
| 332 | .Fa dev_name |
| 333 | and |
| 334 | .Fa unit , |
| 335 | respectively. |
| 336 | .Fn cam_get_device |
| 337 | can handle strings of the following forms, at least: |
| 338 | .Pp |
| 339 | .Bl -tag -width 1234 -compact |
| 340 | .It /dev/foo0a |
| 341 | .It /dev/foo1s2c |
| 342 | .It foo0 |
| 343 | .It foo0a |
| 344 | .It nfoo0 |
| 345 | .El |
| 346 | .Pp |
| 347 | .Fn cam_get_device |
| 348 | is provided as a convenience function for applications that need to provide |
| 349 | functionality similar to |
| 350 | .Fn cam_open_device . |
| 351 | Programmers are encouraged to use more deterministic methods of obtaining |
| 352 | device names and unit numbers if possible. |
| 353 | .Sh RETURN VALUES |
| 354 | .Fn cam_open_device , |
| 355 | .Fn cam_open_spec_device , |
| 356 | .Fn cam_open_btl , |
| 357 | and |
| 358 | .Fn cam_open_pass |
| 359 | return a pointer to a |
| 360 | .Va cam_device |
| 361 | structure, or NULL if there was an error. |
| 362 | .Pp |
| 363 | .Fn cam_getccb |
| 364 | returns an allocated and partially initialized CCB, or NULL if allocation |
| 365 | of the CCB failed. |
| 366 | .Pp |
| 367 | .Fn cam_send_ccb |
| 368 | returns a value of -1 if an error occurred, and |
| 369 | .Va errno |
| 370 | is set to indicate the error. |
| 371 | .Pp |
| 372 | .Fn cam_path_string |
| 373 | returns a filled printing prefix string as a convenience. This is the same |
| 374 | .Fa str |
| 375 | that is passed into |
| 376 | .Fn cam_path_string . |
| 377 | .Pp |
| 378 | .Fn cam_device_dup |
| 379 | returns a copy of the |
| 380 | .Va device |
| 381 | passed in, or NULL if an error occurred. |
| 382 | .Pp |
| 383 | .Fn cam_get_device |
| 384 | returns 0 for success, and -1 to indicate failure. |
| 385 | .Pp |
| 386 | If an error is returned from one of the base CAM library functions |
| 387 | described here, the reason for the error is generally printed in the global |
| 388 | string |
| 389 | .Va cam_errbuf |
| 390 | which is |
| 391 | .Dv CAM_ERRBUF_SIZE |
| 392 | characters long. |
| 393 | .Sh SEE ALSO |
| 394 | .Xr cam_cdbparse 3 , |
| 395 | .Xr pass 4 , |
| 396 | .Xr camcontrol 8 |
| 397 | .Sh HISTORY |
| 398 | The CAM library first appeared in |
| 399 | .Fx 3.0 . |
| 400 | .Sh AUTHORS |
| 401 | .An Kenneth Merry Aq Mt ken@FreeBSD.org |
| 402 | .Sh BUGS |
| 403 | .Fn cam_open_device |
| 404 | doesn't check to see if the |
| 405 | .Fa path |
| 406 | passed in is a symlink to something. It also doesn't check to see if the |
| 407 | .Fa path |
| 408 | passed in is an actual |
| 409 | .Xr pass 4 |
| 410 | device. The former would be rather easy to implement, but the latter would |
| 411 | require a definitive way to identify a device node as a |
| 412 | .Xr pass 4 |
| 413 | device. |
| 414 | .Pp |
| 415 | Some of the functions are possibly mis-named or poorly named. |