From e59c03afa63f2fd3a714dca48855911f266ecd89 Mon Sep 17 00:00:00 2001 From: samm2 <samm2@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Mon, 5 Oct 2009 15:53:07 +0000 Subject: [PATCH] FreeBSD: cam_get_umassno rewritten git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@2932 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- smartmontools/CHANGELOG | 4 +- smartmontools/os_freebsd.cpp | 124 ++++++++--------------------------- 2 files changed, 32 insertions(+), 96 deletions(-) diff --git a/smartmontools/CHANGELOG b/smartmontools/CHANGELOG index da4ecf505..fcdea8d7f 100644 --- a/smartmontools/CHANGELOG +++ b/smartmontools/CHANGELOG @@ -43,9 +43,11 @@ NOTES FOR FUTURE RELEASES: see TODO file. <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> + [AS] FreeBSD: cam_get_umassno rewritten using XPT_PATH_INQ + [AS] FreeBSD: do not open/close cam device on every request for SCSI disks. Use com->camdev both for SCSI and ATAPICAM. - + [AS] FreeBSD: added support for the ada disks, based on agapon patch [CF] Add names for attributes 184 and 188, see ticket #17. diff --git a/smartmontools/os_freebsd.cpp b/smartmontools/os_freebsd.cpp index d4e9964ca..fcaa2a512 100644 --- a/smartmontools/os_freebsd.cpp +++ b/smartmontools/os_freebsd.cpp @@ -1708,102 +1708,36 @@ scsi_device * freebsd_smart_interface::get_scsi_device(const char * name, const } static int -cam_getumassno(char * devname) { +cam_get_umassno(char * devname) { + struct cam_device *cam_dev; union ccb ccb; - int bufsize, fd; - unsigned int i; - int error = -1; - char devstring[256]; - - if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { - warn("couldn't open %s", XPT_DEVICE); - return(1); - } - bzero(&ccb, sizeof(union ccb)); - - ccb.ccb_h.path_id = CAM_XPT_PATH_ID; - ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; - ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; - ccb.ccb_h.func_code = XPT_DEV_MATCH; - bufsize = sizeof(struct dev_match_result) * 100; - ccb.cdm.match_buf_len = bufsize; - ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); - - if (ccb.cdm.matches == NULL) { - warnx("can't malloc memory for matches"); - close(fd); - return(1); + int bus=-1; + + // open CAM device + if ((cam_dev = cam_open_device(devname,O_RDWR)) == NULL) { + // open failue + perror("cam_open_device"); + return -1; } - ccb.cdm.num_matches = 0; - /* - * We fetch all nodes, since we display most of them in the default - * case, and all in the verbose case. - */ - ccb.cdm.num_patterns = 0; - ccb.cdm.pattern_buf_len = 0; - /* - * We do the ioctl multiple times if necessary, in case there are - * more than 100 nodes in the EDT. - */ - - do { - if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { - warn("error sending CAMIOCOMMAND ioctl"); - error = -1; - break; - } - if ((ccb.ccb_h.status != CAM_REQ_CMP) - || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) - && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) - { - warnx("got CAM error %#x, CDM error %d\n", - ccb.ccb_h.status, ccb.cdm.status); - error = -1; - break; - } - - struct bus_match_result *bus_result = 0; - for (i = 0; i < ccb.cdm.num_matches; i++) { - switch (ccb.cdm.matches[i].type) { - case DEV_MATCH_BUS: { - // struct bus_match_result *bus_result; - bus_result = - &ccb.cdm.matches[i].result.bus_result; - break; - } - case DEV_MATCH_DEVICE: { - /* we are not interested in device name */ - break; - } - case DEV_MATCH_PERIPH: { - struct periph_match_result *periph_result; - - periph_result = - &ccb.cdm.matches[i].result.periph_result; - - snprintf(devstring,sizeof(devstring),"%s%d",periph_result->periph_name,periph_result->unit_number); - if(strcmp(devstring,devname)==0){ /* found our device */ - if(strcmp(bus_result->dev_name,"umass-sim")) { - close(fd); - return -1; /* non usb device found, giving up */ - } - /* return bus number */ - return bus_result->unit_number; - } - break; - } - - default: - fprintf(stdout, "WARN: unknown match type\n"); - break; - } + + // zero the payload + bzero(&(&ccb.ccb_h)[1], PATHINQ_SETTINGS_SIZE); + ccb.ccb_h.func_code = XPT_PATH_INQ; // send PATH_INQ to the device + if (ioctl(cam_dev->fd, CAMIOCOMMAND, &ccb) == -1) { + warn("Get Transfer Settings CCB failed\n" + "%s", strerror(errno)); + bus=-1; + } + else { + // now check if we are working with USB device, see umass.c + if(strcmp(ccb.cpi.sim_vid,"FreeBSD") == 0 + && strcmp(ccb.cpi.hba_vid,"USB SCSI")==0) { + bus=ccb.cpi.bus_id; // bus_id will match umass number } - } while ((ccb.ccb_h.status == CAM_REQ_CMP) - && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); - - close(fd); - free(ccb.cdm.matches); - return(error); /* no device found */ + } + // close cam device, we don`t need it anymore + cam_close_device(cam_dev); + return bus; } @@ -2240,13 +2174,13 @@ static int usbdevlist(int busno,unsigned short & vendor_id, #endif } -// Get USB bridge ID for "/dev/daX" +// Get USB bridge ID for the CAM device static bool get_usb_id(const char * path, unsigned short & vendor_id, unsigned short & product_id, unsigned short & version) { if (strlen(path) < 5) return false; - int bus = cam_getumassno((char *)path+5); + int bus = cam_get_umassno((char *)path+5); if (bus == -1) return false; -- GitLab