cam_get_device, cam_open_device: make behavior simpler and more deterministic
Remove or re-work support for the several features from the past: - remove incomplete support for trimming slice/partition names - remove mapping from old device names "sd" and "st" - remove whitespace trimming - remove unconditional skipping of leading 'r' in a device name - skip leading 'n' or 'e' only if the following device name matches a list of known devices that support no-rewind and eject-on-close features; currently this is only sa(4) - reflect the above changes in comments in code and in cam(3) - remove a note cautioning against use of cam_get_device and cam_open_device in cam(3) Reviewed by: mjacob
This commit is contained in:
parent
921f8a1b40
commit
5bcc8fafda
@ -190,12 +190,6 @@ into a device name and unit number.
|
|||||||
Once the device name and unit number
|
Once the device name and unit number
|
||||||
are determined, a lookup is performed to determine the passthrough device
|
are determined, a lookup is performed to determine the passthrough device
|
||||||
that corresponds to the given device.
|
that corresponds to the given device.
|
||||||
.Fn cam_open_device
|
|
||||||
is rather simple to use, but it is not really suitable for general use
|
|
||||||
because its behavior is not necessarily deterministic.
|
|
||||||
Programmers writing
|
|
||||||
new applications should make the extra effort to use one of the other open
|
|
||||||
routines documented below.
|
|
||||||
.Pp
|
.Pp
|
||||||
.Fn cam_open_spec_device
|
.Fn cam_open_spec_device
|
||||||
opens the
|
opens the
|
||||||
@ -354,19 +348,15 @@ respectively.
|
|||||||
can handle strings of the following forms, at least:
|
can handle strings of the following forms, at least:
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width 1234 -compact
|
.Bl -tag -width 1234 -compact
|
||||||
.It /dev/foo0a
|
.It /dev/foo1
|
||||||
.It /dev/foo1s2c
|
|
||||||
.It foo0
|
.It foo0
|
||||||
.It foo0a
|
.It nsa2
|
||||||
.It nfoo0
|
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
.Fn cam_get_device
|
.Fn cam_get_device
|
||||||
is provided as a convenience function for applications that need to provide
|
is provided as a convenience function for applications that need to provide
|
||||||
functionality similar to
|
functionality similar to
|
||||||
.Fn cam_open_device .
|
.Fn cam_open_device .
|
||||||
Programmers are encouraged to use more deterministic methods of obtaining
|
|
||||||
device names and unit numbers if possible.
|
|
||||||
.Sh RETURN VALUES
|
.Sh RETURN VALUES
|
||||||
.Fn cam_open_device ,
|
.Fn cam_open_device ,
|
||||||
.Fn cam_open_spec_device ,
|
.Fn cam_open_spec_device ,
|
||||||
|
@ -42,14 +42,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <cam/scsi/scsi_pass.h>
|
#include <cam/scsi/scsi_pass.h>
|
||||||
#include "camlib.h"
|
#include "camlib.h"
|
||||||
|
|
||||||
struct cam_devequiv {
|
|
||||||
char *given_dev;
|
|
||||||
char *real_dev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cam_devequiv devmatchtable[] = {
|
static const char *nonrewind_devs[] = {
|
||||||
{"sd", "da"},
|
"sa"
|
||||||
{"st", "sa"}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
char cam_errbuf[CAM_ERRBUF_SIZE];
|
char cam_errbuf[CAM_ERRBUF_SIZE];
|
||||||
@ -103,19 +98,14 @@ cam_freeccb(union ccb *ccb)
|
|||||||
/*
|
/*
|
||||||
* Take a device name or path passed in by the user, and attempt to figure
|
* Take a device name or path passed in by the user, and attempt to figure
|
||||||
* out the device name and unit number. Some possible device name formats are:
|
* out the device name and unit number. Some possible device name formats are:
|
||||||
* /dev/foo0a
|
* /dev/foo0
|
||||||
* /dev/rfoo0a
|
|
||||||
* /dev/rfoos2c
|
|
||||||
* foo0
|
* foo0
|
||||||
* foo0a
|
* nfoo0
|
||||||
* rfoo0
|
|
||||||
* rfoo0a
|
|
||||||
* nrfoo0
|
|
||||||
*
|
|
||||||
* If the caller passes in an old style device name like 'sd' or 'st',
|
|
||||||
* it will be converted to the new style device name based upon devmatchtable
|
|
||||||
* above.
|
|
||||||
*
|
*
|
||||||
|
* Some peripheral drivers create separate device nodes with 'n' prefix for
|
||||||
|
* non-rewind operations. Currently only sa(4) tape driver has this feature.
|
||||||
|
* We extract pure peripheral name as device name for this special case.
|
||||||
|
*
|
||||||
* Input parameters: device name/path, length of devname string
|
* Input parameters: device name/path, length of devname string
|
||||||
* Output: device name, unit number
|
* Output: device name, unit number
|
||||||
* Return values: returns 0 for success, -1 for failure
|
* Return values: returns 0 for success, -1 for failure
|
||||||
@ -127,7 +117,7 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
|
|||||||
char *tmpstr, *tmpstr2;
|
char *tmpstr, *tmpstr2;
|
||||||
char *newpath;
|
char *newpath;
|
||||||
int unit_offset;
|
int unit_offset;
|
||||||
int i, found = 0;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
@ -142,10 +132,6 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
|
|||||||
newpath = (char *)strdup(path);
|
newpath = (char *)strdup(path);
|
||||||
tmpstr = newpath;
|
tmpstr = newpath;
|
||||||
|
|
||||||
/* Get rid of any leading white space */
|
|
||||||
while (isspace(*tmpstr) && (*tmpstr != '\0'))
|
|
||||||
tmpstr++;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see whether we have an absolute pathname.
|
* Check to see whether we have an absolute pathname.
|
||||||
*/
|
*/
|
||||||
@ -166,54 +152,15 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
|
|||||||
* Check to see whether the user has given us a nonrewound tape
|
* Check to see whether the user has given us a nonrewound tape
|
||||||
* device.
|
* device.
|
||||||
*/
|
*/
|
||||||
if (*tmpstr == 'n')
|
if (*tmpstr == 'n' || *tmpstr == 'e') {
|
||||||
tmpstr++;
|
for (i = 0; i < sizeof(nonrewind_devs)/sizeof(char *); i++) {
|
||||||
|
int len = strlen(nonrewind_devs[i]);
|
||||||
if (*tmpstr == '\0') {
|
if (strncmp(tmpstr + 1, nonrewind_devs[i], len) == 0) {
|
||||||
sprintf(cam_errbuf, "%s: no text after leading 'n'", func_name);
|
if (isdigit(tmpstr[len + 1])) {
|
||||||
free(newpath);
|
tmpstr++;
|
||||||
return(-1);
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/*
|
|
||||||
* See if the user has given us a character device.
|
|
||||||
*/
|
|
||||||
if (*tmpstr == 'r')
|
|
||||||
tmpstr++;
|
|
||||||
|
|
||||||
if (*tmpstr == '\0') {
|
|
||||||
sprintf(cam_errbuf, "%s: no text after leading 'r'", func_name);
|
|
||||||
free(newpath);
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to get rid of any trailing white space or partition letters.
|
|
||||||
*/
|
|
||||||
tmpstr2 = &tmpstr[strlen(tmpstr) - 1];
|
|
||||||
|
|
||||||
while ((*tmpstr2 != '\0') && (tmpstr2 > tmpstr) &&(!isdigit(*tmpstr2))){
|
|
||||||
*tmpstr2 = '\0';
|
|
||||||
tmpstr2--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to see whether we have been given a partition with a slice
|
|
||||||
* name. If so, get rid of the slice name/number.
|
|
||||||
*/
|
|
||||||
if (strlen(tmpstr) > 3) {
|
|
||||||
/*
|
|
||||||
* Basically, we're looking for a string that ends in the
|
|
||||||
* following general manner: 1s1 -- a number, the letter
|
|
||||||
* s, and then another number. This indicates that the
|
|
||||||
* user has given us a slice. We substitute nulls for the
|
|
||||||
* s and the slice number.
|
|
||||||
*/
|
|
||||||
if ((isdigit(tmpstr[strlen(tmpstr) - 1]))
|
|
||||||
&& (tmpstr[strlen(tmpstr) - 2] == 's')
|
|
||||||
&& (isdigit(tmpstr[strlen(tmpstr) - 3]))) {
|
|
||||||
tmpstr[strlen(tmpstr) - 1] = '\0';
|
|
||||||
tmpstr[strlen(tmpstr) - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,20 +228,7 @@ cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
|
|||||||
*/
|
*/
|
||||||
tmpstr[strlen(tmpstr) - unit_offset] = '\0';
|
tmpstr[strlen(tmpstr) - unit_offset] = '\0';
|
||||||
|
|
||||||
/*
|
strlcpy(dev_name, tmpstr, devnamelen);
|
||||||
* Look through our equivalency table and see if the device name
|
|
||||||
* the user gave us is an old style device name. If so, translate
|
|
||||||
* it to the new style device name.
|
|
||||||
*/
|
|
||||||
for (i = 0;i < (sizeof(devmatchtable)/sizeof(struct cam_devequiv));i++){
|
|
||||||
if (strcmp(tmpstr, devmatchtable[i].given_dev) == 0) {
|
|
||||||
strlcpy(dev_name,devmatchtable[i].real_dev, devnamelen);
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found == 0)
|
|
||||||
strlcpy(dev_name, tmpstr, devnamelen);
|
|
||||||
|
|
||||||
/* Clean up allocated memory */
|
/* Clean up allocated memory */
|
||||||
free(newpath);
|
free(newpath);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user