Ejemplo n.º 1
0
ATF_TC_BODY(cam_get_device_negative_test_root, tc)
{
	char parsed_dev_name[DEV_IDLEN + 1];
	int parsed_unit;

	ATF_REQUIRE_MSG(cam_get_device("/", parsed_dev_name,
	    nitems(parsed_dev_name), &parsed_unit) == -1,
	    "cam_get_device succeeded unexpectedly");
}
Ejemplo n.º 2
0
/* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed
 * together. The 'flags' argument is ignored in FreeBSD.
 * Returns >= 0 if successful, otherwise returns negated errno. */
int
scsi_pt_open_flags(const char * device_name,
                   int flags __attribute__ ((unused)), int verbose)
{
    struct freebsd_dev_channel *fdchan;
    struct cam_device* cam_dev;
    int k;

    if (NULL == sg_warnings_strm)
        sg_warnings_strm = stderr;
    // Search table for a free entry
    for (k = 0; k < FREEBSD_MAXDEV; k++)
        if (! devicetable[k])
            break;

    // If no free entry found, return error.  We have max allowed number
    // of "file descriptors" already allocated.
    if (k == FREEBSD_MAXDEV) {
        if (verbose)
            fprintf(sg_warnings_strm, "too many open file descriptors "
                    "(%d)\n", FREEBSD_MAXDEV);
        errno = EMFILE;
        return -1;
    }

    fdchan = (struct freebsd_dev_channel *)
                calloc(1,sizeof(struct freebsd_dev_channel));
    if (fdchan == NULL) {
        // errno already set by call to calloc()
        return -1;
    }

    if (! (fdchan->devname = (char *)calloc(1, DEV_IDLEN+1)))
         return -1;

    if (cam_get_device(device_name, fdchan->devname, DEV_IDLEN,
                       &(fdchan->unitnum)) == -1) {
        if (verbose)
            fprintf(sg_warnings_strm, "bad device name structure\n");
        errno = EINVAL;
        return -1;
    }

    if (! (cam_dev = cam_open_spec_device(fdchan->devname,
                                          fdchan->unitnum, O_RDWR, NULL))) {
        if (verbose)
            fprintf(sg_warnings_strm, "cam_open_spec_device: %s\n",
                    cam_errbuf);
        errno = EPERM;    /* permissions or no CAM */
        return -1;
    }
    fdchan->cam_dev = cam_dev;
    // return pointer to "file descriptor" table entry, properly offset.
    devicetable[k] = fdchan;
    return k + FREEBSD_FDOFFSET;
}
Ejemplo n.º 3
0
ATF_TC_BODY(cam_get_device_positive_test, tc)
{
	char expected_dev_name[] = "foo";
	char parsed_dev_name[DEV_IDLEN + 1];
	int expected_unit, parsed_unit;

	expected_unit = 1;

	ATF_REQUIRE_MSG(cam_get_device("/dev/foo1", parsed_dev_name,
	    nitems(parsed_dev_name), &parsed_unit) == 0,
	    "cam_get_device failed");
	ATF_REQUIRE_STREQ(parsed_dev_name, expected_dev_name);
	ATF_REQUIRE(parsed_unit == expected_unit);

	strcpy(parsed_dev_name, "");
	parsed_unit = -1;

	ATF_REQUIRE_MSG(cam_get_device("foo1", parsed_dev_name,
	    nitems(parsed_dev_name), &parsed_unit) == 0,
	    "cam_get_device failed");
	ATF_REQUIRE_STREQ(parsed_dev_name, expected_dev_name);
	ATF_REQUIRE(parsed_unit == expected_unit);
}
Ejemplo n.º 4
0
/*
 * Backwards compatible wrapper for the real open routine.  This translates
 * a pathname into a device name and unit number for use with the real open
 * routine.
 */
struct cam_device *
cam_open_device(const char *path, int flags)
{
	int unit;
	char dev_name[DEV_IDLEN + 1];

	/*
	 * cam_get_device() has already put an error message in cam_errbuf,
	 * so we don't need to.
	 */
	if (cam_get_device(path, dev_name, sizeof(dev_name), &unit) == -1)
		return(NULL);

	return(cam_lookup_pass(dev_name, unit, flags, path, NULL));
}
Ejemplo n.º 5
0
/* open ata device */
int ata_open(ATA **ataptr, const char *device) {
	int rc;
	assert(ataptr != NULL);
	
	*ataptr = malloc(sizeof(ATA));
	{
		ATA *ata = *ataptr;
		if (ata == NULL)
			err(EX_SOFTWARE, NULL);
		ata->devhandle.fd = -1;

		/* TODO better detection of SCSI/SAT */
		ata->access_mode = ACCESS_MODE_ATA;
		if (strncmp(device, scsi_prefix_da, strlen(scsi_prefix_da)) == 0)
			ata->access_mode = ACCESS_MODE_SAT;

		switch (ata->access_mode) {
		case ACCESS_MODE_ATA:
			rc = open( device, O_RDONLY );
			if (rc > 0)
				ata->devhandle.fd = rc;
			break;
		case ACCESS_MODE_SAT:
			rc = cam_get_device( device, ata->devhandle.camdevname,
					     DEV_IDLEN,
					     &(ata->devhandle.camunit) );
			if (rc != 0)
				goto fail;
			ata->devhandle.camdev = cam_open_spec_device(
				ata->devhandle.camdevname,
				ata->devhandle.camunit,	O_RDONLY, NULL );
			if (ata->devhandle.camdev == NULL) {
				rc = -1;
				warnx("%s", cam_errbuf);
				goto fail;
			}
			
			break;
		}
	}
	return rc;
fail:
	free(*ataptr);
	return rc;
}
Ejemplo n.º 6
0
/* Note that CAM (circa FreeBSD 9) cannot directly communicate with a SAS
 * expander because it isn't a SCSI device. FreeBSD assumes each SAS
 * expander is paired with a SES (enclosure) device. This seems to be true
 * for SAS-2 expanders but not the older SAS-1 expanders. Hence device_name
 * will be something like /dev/ses0 . */
int
smp_initiator_open(const char * device_name, int subvalue,
                   const char * i_params, uint64_t sa,
                   struct smp_target_obj * tobj, int verbose)
{
    struct cam_device* cam_dev;
    struct tobj_cam_t * tcp;

    if (i_params) { ; }     /* unused, suppress warning */
    if ((NULL == tobj) || (NULL == device_name))
        return -1;
    memset(tobj, 0, sizeof(struct smp_target_obj));
    strncpy(tobj->device_name, device_name, SMP_MAX_DEVICE_NAME);
    if (sa)
        sg_put_unaligned_be64(sa, tobj->sas_addr + 0);
    tobj->interface_selector = I_CAM;
    tcp = (struct tobj_cam_t *)
                calloc(1, sizeof(struct tobj_cam_t));
    if (tcp == NULL) {
        // errno already set by call to calloc()
        return -1;
    }
    if (cam_get_device(device_name, tcp->devname, DEV_IDLEN,
                       &(tcp->unitnum)) == -1) {
        if (verbose)
            fprintf(stderr, "bad device name structure\n");
        free(tcp);
        return -1;
    }
    if (! (cam_dev = cam_open_spec_device(tcp->devname, tcp->unitnum,
                                          O_RDWR, NULL))) {
        fprintf(stderr, "cam_open_spec_device: %s\n", cam_errbuf);
        free(tcp);
        return -1;
    }
    tcp->cam_dev = cam_dev;
    tobj->vp = tcp;
    tobj->opened = 1;
    tobj->subvalue = subvalue;  /* unused */
    return 0;
}
Ejemplo n.º 7
0
/*
 * Core interface function to lowlevel SCSI interface.
 */
static inline bool do_scsi_cmd_page(int fd, const char *device_name,
                                    void *cdb, unsigned int cdb_len,
                                    void *cmd_page, unsigned int cmd_page_len,
                                    int direction)
{
   int unitnum, len;
   union ccb *ccb;
   char errbuf[128];
   char cam_devicename[64];
   struct cam_device *cam_dev;
   SCSI_PAGE_SENSE sense;
   bool retval = false;

   /*
    * See what CAM device to use.
    */
   if (cam_get_device(device_name, cam_devicename, sizeof(cam_devicename), &unitnum) == -1) {
      berrno be;

      Emsg2(M_ERROR, 0, _("Failed to find CAM device for %s: ERR=%s\n"),
            device_name, be.bstrerror());
      Dmsg2(010, "Failed to find CAM device for %s: ERR=%s\n",
            device_name, be.bstrerror());
      return false;
   }

   cam_dev = cam_open_spec_device(cam_devicename, unitnum, O_RDWR, NULL);
   if (!cam_dev) {
      berrno be;

      Emsg2(M_ERROR, 0, _("Failed to open CAM device for %s: ERR=%s\n"),
            device_name, be.bstrerror());
      Dmsg2(010, "Failed to open CAM device for %s: ERR=%s\n",
            device_name, be.bstrerror());
      return false;
   }

   ccb = cam_getccv(cam_dev);
   if (!ccb) {
      Emsg1(M_ERROR, 0, _("Failed to allocate new ccb for %s\n"),
            device_name);
      Dmsg1(0, "Failed to allocate new ccb for %s\n",
            device_name);
      goto bail_out;
   }

   /*
    * Clear out structure, except for header that was filled for us.
    */
   memset(&ccb->ccb_h)[1], 0, sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));

   cam_fill_csio(&ccb->csio,
                 1, /* retries */
                 NULL, /* cbfcnp */
                 direction, /* flags */
                 MSG_SIMPLE_Q_TAG,, /* tagaction */
                 cmd_page, /* dataptr */
                 cmd_page_len, /* datalen */
                 sizeof(sense), /* senselength */
                 cdb_len, /* cdblength  */
                 15000 /* timeout (millisecs) */);
   memcpy(ccb->csio.cdb_io.cdb_bytes, cdb, SPP_SP_CMD_LEN);

   if (cam_send_ccb(cam_dev, ccb) < 0) {
      Emsg2(M_ERROR, 0, _("Failed to send ccb to device %s: %s\n"),
            device_name, cam_error_string(cam_dev, ccb, errbuf, sizeof(errbuf),
                                          CAM_ESF_ALL, CAM_EPF_ALL));
      Dmsg2(010, "Failed to send ccb to device %s: %s\n",
            device_name, cam_error_string(cam_dev, ccb, errbuf, sizeof(errbuf),
                                          CAM_ESF_ALL, CAM_EPF_ALL));
      cam_freeccb(ccb);
      goto bail_out;
   }

   /*
    * Retrieve the SCSI sense data.
    */
   if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) ||
       ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)) {
      if ((SAM_STAT_CHECK_CONDITION == ccb->csio.scsi_status) ||
          (SAM_STAT_COMMAND_TERMINATED == ccb->csio.scsi_status)) {
         len = sizeof(sense) - ccb->csio.sense_resid;
         if (len) {
            memcpy(&sense, &(ccb->csio.sense_data), len);
         }
      }
   }

   retval = true;

bail_out:
   /*
    * Close the CAM device.
    */
   cam_close_device(cam_dev);
   return retval;
}