Beispiel #1
0
/*
 * mrsas_bus_scan:	Perform bus scan
 * input:			Adapter instance soft state
 *
 * This mrsas_bus_scan function is needed for FreeBSD 7.x.  Also, it should not
 * be called in FreeBSD 8.x and later versions, where the bus scan is
 * automatic.
 */
int
mrsas_bus_scan(struct mrsas_softc *sc)
{
    union ccb *ccb_0;
    union ccb *ccb_1;

    if ((ccb_0 = xpt_alloc_ccb()) == NULL) {
        return (ENOMEM);
    }
    if ((ccb_1 = xpt_alloc_ccb()) == NULL) {
        xpt_free_ccb(ccb_0);
        return (ENOMEM);
    }
    mtx_lock(&sc->sim_lock);
    if (xpt_create_path(&ccb_0->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_0),
                        CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
        xpt_free_ccb(ccb_0);
        xpt_free_ccb(ccb_1);
        mtx_unlock(&sc->sim_lock);
        return (EIO);
    }
    if (xpt_create_path(&ccb_1->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_1),
                        CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
        xpt_free_ccb(ccb_0);
        xpt_free_ccb(ccb_1);
        mtx_unlock(&sc->sim_lock);
        return (EIO);
    }
    mtx_unlock(&sc->sim_lock);
    xpt_rescan(ccb_0);
    xpt_rescan(ccb_1);

    return (0);
}
/*
 * mrsas_bus_scan:           Perform bus scan 
 * input:                    Adapter instance soft state  
 *
 * This mrsas_bus_scan function is needed for FreeBSD 7.x.  Also, it should
 * not be called in FreeBSD 8.x and later versions, where the bus scan is 
 * automatic. 
 */ 
int mrsas_bus_scan(struct mrsas_softc *sc)
{
    union ccb *ccb_0;
    union ccb *ccb_1;

    lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
    if ((ccb_0 = xpt_alloc_ccb()) == NULL) {
        lockmgr(&sc->sim_lock, LK_RELEASE);
        return(ENOMEM);
    }

    if ((ccb_1 = xpt_alloc_ccb()) == NULL) {
	xpt_free_ccb(ccb_0);
        lockmgr(&sc->sim_lock, LK_RELEASE);
        return(ENOMEM);
    } 

    if (xpt_create_path(&ccb_0->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_0),
            CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP){
        xpt_free_ccb(ccb_0);
        xpt_free_ccb(ccb_1);
        lockmgr(&sc->sim_lock, LK_RELEASE);
        return(EIO);
    }

    if (xpt_create_path(&ccb_1->ccb_h.path, xpt_periph, cam_sim_path(sc->sim_1),
            CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP){
        xpt_free_ccb(ccb_0);
        xpt_free_ccb(ccb_1);
        lockmgr(&sc->sim_lock, LK_RELEASE);
        return(EIO);
    }

    xpt_setup_ccb(&ccb_0->ccb_h, ccb_0->ccb_h.path, 5/*priority (low)*/);
    ccb_0->ccb_h.func_code = XPT_SCAN_BUS;
    ccb_0->ccb_h.cbfcnp = mrsas_rescan_callback;
    ccb_0->crcn.flags = CAM_FLAG_NONE;
    xpt_action(ccb_0); /* scan is now in progress */

    xpt_setup_ccb(&ccb_1->ccb_h, ccb_1->ccb_h.path, 5/*priority (low)*/);
    ccb_1->ccb_h.func_code = XPT_SCAN_BUS;
    ccb_1->ccb_h.cbfcnp = mrsas_rescan_callback;
    ccb_1->crcn.flags = CAM_FLAG_NONE;
    xpt_action(ccb_1); /* scan is now in progress */

    lockmgr(&sc->sim_lock, LK_RELEASE);

    return(0);
}
Beispiel #3
0
static void
ahci_cam_rescan(struct ahci_port *ap)
{
	struct cam_path *path;
	union ccb *ccb;
	int status;
	int i;

	if (ap->ap_flags & AP_F_SCAN_RUNNING) {
		ap->ap_flags |= AP_F_SCAN_REQUESTED;
		return;
	}
	ap->ap_flags |= AP_F_SCAN_RUNNING;
	for (i = 0; i < AHCI_MAX_PMPORTS; ++i) {
		ap->ap_ata[i]->at_features |= ATA_PORT_F_RESCAN;
	}

	status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim),
				 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
	if (status != CAM_REQ_CMP)
		return;

	ccb = xpt_alloc_ccb();
	xpt_setup_ccb(&ccb->ccb_h, path, 5);	/* 5 = low priority */
	ccb->ccb_h.func_code = XPT_ENG_EXEC;
	ccb->ccb_h.cbfcnp = ahci_cam_rescan_callback;
	ccb->ccb_h.sim_priv.entries[0].ptr = ap;
	ccb->crcn.flags = CAM_FLAG_NONE;
	xpt_action_async(ccb);
}
Beispiel #4
0
static int
ic_scan(isc_session_t *sp)
{
     union ccb	*ccb;

     debug_called(8);
     sdebug(2, "scanning sid=%d", sp->sid);

     sp->flags &= ~ISC_CAMDEVS;
     sp->flags |= ISC_SCANWAIT;

     ccb = xpt_alloc_ccb();
     ccb->ccb_h.path		= sp->cam_path;
     ccb->ccb_h.cbfcnp		= scan_callback;
     ccb->ccb_h.spriv_ptr0	= sp;

     xpt_rescan(ccb);

     while(sp->flags & ISC_SCANWAIT)
	  tsleep(sp, PRIBIO, "ffp", 5*hz); // the timeout time should
					    // be configurable
     sdebug(2, "# of luns=%d", sp->target_nluns);

     if(sp->target_nluns > 0) {
	  sp->flags |= ISC_CAMDEVS;
	  return 0;
     }

     return ENODEV;
}
Beispiel #5
0
/*
 * Function name:	tw_osli_request_bus_scan
 * Description:		Requests CAM for a scan of the bus.
 *
 * Input:		sc	-- ptr to per ctlr structure
 * Output:		None
 * Return value:	0	-- success
 *			non-zero-- failure
 */
TW_INT32
tw_osli_request_bus_scan(struct twa_softc *sc)
{
	union ccb	*ccb;

	tw_osli_dbg_dprintf(3, sc, "entering");

	/* If we get here before sc->sim is initialized, return an error. */
	if (!(sc->sim))
		return(ENXIO);
	if ((ccb = xpt_alloc_ccb()) == NULL)
		return(ENOMEM);
	lockmgr(sc->sim_lock, LK_EXCLUSIVE);
	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(sc->sim),
	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
		xpt_free_ccb(ccb);
		lockmgr(sc->sim_lock, LK_RELEASE);
		return(EIO);
	}

	xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5/*priority (low)*/);
	ccb->ccb_h.func_code = XPT_SCAN_BUS;
	ccb->ccb_h.cbfcnp = twa_bus_scan_cb;
	ccb->crcn.flags = CAM_FLAG_NONE;
	xpt_action(ccb);

	lockmgr(sc->sim_lock, LK_RELEASE);
	return(0);
}
Beispiel #6
0
static void
ahci_xpt_rescan(struct ahci_port *ap)
{
	struct cam_path *path;
	union ccb *ccb;
	int status;

	status = xpt_create_path(&path, xpt_periph, cam_sim_path(ap->ap_sim),
				 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
	if (status != CAM_REQ_CMP)
		return;

	ccb = xpt_alloc_ccb();
	xpt_setup_ccb(&ccb->ccb_h, path, 5);	/* 5 = low priority */
	ccb->ccb_h.func_code = XPT_SCAN_BUS;
	ccb->ccb_h.cbfcnp = ahci_cam_rescan_callback;
	ccb->ccb_h.sim_priv.entries[0].ptr = ap;
	ccb->crcn.flags = CAM_FLAG_NONE;
	xpt_action_async(ccb);
}
Beispiel #7
0
int
tws_bus_scan(struct tws_softc *sc)
{
    union ccb       *ccb;

    TWS_TRACE_DEBUG(sc, "entry", sc, 0);
    if (!(sc->sim))
        return(ENXIO);
    ccb = xpt_alloc_ccb();
    mtx_lock(&sc->sim_lock);
    if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim),
                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
	mtx_unlock(&sc->sim_lock);
        xpt_free_ccb(ccb);
        return(EIO);
    }
    xpt_rescan(ccb);
    mtx_unlock(&sc->sim_lock);
    return(0);
}
Beispiel #8
0
/*
 * Function name:	tw_osli_request_bus_scan
 * Description:		Requests CAM for a scan of the bus.
 *
 * Input:		sc	-- ptr to per ctlr structure
 * Output:		None
 * Return value:	0	-- success
 *			non-zero-- failure
 */
TW_INT32
tw_osli_request_bus_scan(struct twa_softc *sc)
{
	union ccb	*ccb;

	tw_osli_dbg_dprintf(3, sc, "entering");

	/* If we get here before sc->sim is initialized, return an error. */
	if (!(sc->sim))
		return(ENXIO);
	if ((ccb = xpt_alloc_ccb()) == NULL)
		return(ENOMEM);
	mtx_lock(sc->sim_lock);
	if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(sc->sim),
	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
		xpt_free_ccb(ccb);
		mtx_unlock(sc->sim_lock);
		return(EIO);
	}

	xpt_rescan(ccb);
	mtx_unlock(sc->sim_lock);
	return(0);
}
Beispiel #9
0
/*
 * Attach all the sub-devices we can find
 */
int
adv_attach(struct adv_softc *adv)
{
	struct ccb_setasync *csa;
	int max_sg;

	/*
	 * Allocate an array of ccb mapping structures.  We put the
	 * index of the ccb_info structure into the queue representing
	 * a transaction and use it for mapping the queue to the
	 * upper level SCSI transaction it represents.
	 */
	adv->ccb_infos = kmalloc(sizeof(*adv->ccb_infos) * adv->max_openings,
				M_DEVBUF, M_WAITOK);
	adv->init_level++;
		
	/*
	 * Create our DMA tags.  These tags define the kinds of device
	 * accessible memory allocations and memory mappings we will 
	 * need to perform during normal operation.
	 *
	 * Unless we need to further restrict the allocation, we rely
	 * on the restrictions of the parent dmat, hence the common
	 * use of MAXADDR and MAXSIZE.
	 *
	 * The ASC boards use chains of "queues" (the transactional
	 * resources on the board) to represent long S/G lists.
	 * The first queue represents the command and holds a
	 * single address and data pair.  The queues that follow
	 * can each hold ADV_SG_LIST_PER_Q entries.  Given the
	 * total number of queues, we can express the largest
	 * transaction we can map.  We reserve a few queues for
	 * error recovery.  Take those into account as well.
	 *
	 * There is a way to take an interrupt to download the
	 * next batch of S/G entries if there are more than 255
	 * of them (the counter in the queue structure is a u_int8_t).
	 * We don't use this feature, so limit the S/G list size
	 * accordingly.
	 */
	max_sg = (adv->max_openings - ADV_MIN_FREE_Q - 1) * ADV_SG_LIST_PER_Q;
	if (max_sg > 255)
		max_sg = 255;

	/* DMA tag for mapping buffers into device visible space. */
	if (bus_dma_tag_create(adv->parent_dmat, /*alignment*/1, /*boundary*/0,
			       /*lowaddr*/BUS_SPACE_MAXADDR,
			       /*highaddr*/BUS_SPACE_MAXADDR,
			       /*filter*/NULL, /*filterarg*/NULL,
			       /*maxsize*/MAXPHYS,
			       /*nsegments*/max_sg,
			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
			       /*flags*/BUS_DMA_ALLOCNOW,
			       &adv->buffer_dmat) != 0) {
		return (ENXIO);
	}
	adv->init_level++;

	/* DMA tag for our sense buffers */
	if (bus_dma_tag_create(adv->parent_dmat, /*alignment*/1, /*boundary*/0,
			       /*lowaddr*/BUS_SPACE_MAXADDR,
			       /*highaddr*/BUS_SPACE_MAXADDR,
			       /*filter*/NULL, /*filterarg*/NULL,
			       sizeof(struct scsi_sense_data)*adv->max_openings,
			       /*nsegments*/1,
			       /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
			       /*flags*/0, &adv->sense_dmat) != 0) {
		return (ENXIO);
        }

	adv->init_level++;

	/* Allocation for our sense buffers */
	if (bus_dmamem_alloc(adv->sense_dmat, (void *)&adv->sense_buffers,
			     BUS_DMA_NOWAIT, &adv->sense_dmamap) != 0) {
		return (ENOMEM);
	}

	adv->init_level++;

	/* And permanently map them */
	bus_dmamap_load(adv->sense_dmat, adv->sense_dmamap,
       			adv->sense_buffers,
			sizeof(struct scsi_sense_data)*adv->max_openings,
			adv_map, &adv->sense_physbase, /*flags*/0);

	adv->init_level++;

	/*
	 * Fire up the chip
	 */
	if (adv_start_chip(adv) != 1) {
		kprintf("adv%d: Unable to start on board processor. Aborting.\n",
		       adv->unit);
		return (ENXIO);
	}

	/*
	 * Construct our SIM entry.
	 */
	adv->sim = cam_sim_alloc(adv_action, adv_poll, "adv", adv, adv->unit,
				 &sim_mplock, 1, adv->max_openings, NULL);
	if (adv->sim == NULL)
		return (ENOMEM);

	/*
	 * Register the bus.
	 *
	 * XXX Twin Channel EISA Cards???
	 */
	if (xpt_bus_register(adv->sim, 0) != CAM_SUCCESS) {
		cam_sim_free(adv->sim);
		return (ENXIO);
	}

	if (xpt_create_path(&adv->path, /*periph*/NULL, cam_sim_path(adv->sim),
			    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)
	    != CAM_REQ_CMP) {
		xpt_bus_deregister(cam_sim_path(adv->sim));
		cam_sim_free(adv->sim);
		return (ENXIO);
	}

	csa = &xpt_alloc_ccb()->csa;
	xpt_setup_ccb(&csa->ccb_h, adv->path, /*priority*/5);
	csa->ccb_h.func_code = XPT_SASYNC_CB;
	csa->event_enable = AC_FOUND_DEVICE|AC_LOST_DEVICE;
	csa->callback = advasync;
	csa->callback_arg = adv;
	xpt_action((union ccb *)csa);
	xpt_free_ccb(&csa->ccb_h);

	return (0);
}
Beispiel #10
0
static int
cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
    struct thread *td, d_ioctl_t *cbfnp)
{
	union ccb		*ccb;
	struct ccb_hdr		*hdr;
	struct ccb_hdr_0x18	*hdr18;
	uint8_t			*ccbb, *ccbb18;
	u_int			error;

	hdr18 = (struct ccb_hdr_0x18 *)addr;
	ccb = xpt_alloc_ccb();
	hdr = &ccb->ccb_h;

	hdr->pinfo = hdr18->pinfo;
	hdr->xpt_links = hdr18->xpt_links;
	hdr->sim_links = hdr18->sim_links;
	hdr->periph_links = hdr18->periph_links;
	hdr->retry_count = hdr18->retry_count;
	hdr->cbfcnp = hdr18->cbfcnp;
	hdr->func_code = hdr18->func_code;
	hdr->status = hdr18->status;
	hdr->path = hdr18->path;
	hdr->path_id = hdr18->path_id;
	hdr->target_id = hdr18->target_id;
	hdr->target_lun = hdr18->target_lun;
	if (hdr18->xflags & CAM_EXTLUN_VALID_0x18)
		hdr->target_lun = hdr18->ext_lun;
	hdr->flags = hdr18->flags;
	hdr->xflags = hdr18->xflags;
	hdr->periph_priv = hdr18->periph_priv;
	hdr->sim_priv = hdr18->sim_priv;
	hdr->timeout = hdr18->timeout;
	hdr->softtimeout.tv_sec = 0;
	hdr->softtimeout.tv_usec = 0;

	ccbb = (uint8_t *)&hdr[1];
	ccbb18 = (uint8_t *)&hdr18[1];
	if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) {
		struct ccb_trans_settings *cts;
		struct ccb_trans_settings_0x18 *cts18;

		cts = &ccb->cts;
		cts18 = (struct ccb_trans_settings_0x18 *)hdr18;
		cts->type = cts18->type;
		cts->protocol = cts18->protocol;
		cts->protocol_version = cts18->protocol_version;
		cts->transport = cts18->transport;
		cts->transport_version = cts18->transport_version;
		bcopy(&cts18->proto_specific, &cts->proto_specific,
		    sizeof(cts18->proto_specific));
		bcopy(&cts18->xport_specific, &cts->xport_specific,
		    sizeof(cts18->xport_specific));
	} else {
		bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN);
	}

	error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);

	hdr18->pinfo = hdr->pinfo;
	hdr18->xpt_links = hdr->xpt_links;
	hdr18->sim_links = hdr->sim_links;
	hdr18->periph_links = hdr->periph_links;
	hdr18->retry_count = hdr->retry_count;
	hdr18->cbfcnp = hdr->cbfcnp;
	hdr18->func_code = hdr->func_code;
	hdr18->status = hdr->status;
	hdr18->path = hdr->path;
	hdr18->path_id = hdr->path_id;
	hdr18->target_id = hdr->target_id;
	hdr18->target_lun = hdr->target_lun;
	hdr18->ext_lun = hdr->target_lun;
	hdr18->flags = hdr->flags;
	hdr18->xflags = hdr->xflags | CAM_EXTLUN_VALID_0x18;
	hdr18->periph_priv = hdr->periph_priv;
	hdr18->sim_priv = hdr->sim_priv;
	hdr18->timeout = hdr->timeout;

	if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) {
		struct ccb_trans_settings *cts;
		struct ccb_trans_settings_0x18 *cts18;

		cts = &ccb->cts;
		cts18 = (struct ccb_trans_settings_0x18 *)hdr18;
		cts18->type = cts->type;
		cts18->protocol = cts->protocol;
		cts18->protocol_version = cts->protocol_version;
		cts18->transport = cts->transport;
		cts18->transport_version = cts->transport_version;
		bcopy(&cts->proto_specific, &cts18->proto_specific,
		    sizeof(cts18->proto_specific));
		bcopy(&cts->xport_specific, &cts18->xport_specific,
		    sizeof(cts18->xport_specific));
	} else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
		bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
		cam_compat_translate_dev_match_0x18(ccb);
	} else {
		bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
	}

	xpt_free_ccb(ccb);

	return (error);
}
Beispiel #11
0
static int
cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
    struct thread *td, d_ioctl_t *cbfnp)
{
	union ccb		*ccb;
	struct ccb_hdr		*hdr;
	struct ccb_hdr_0x17	*hdr17;
	uint8_t			*ccbb, *ccbb17;
	u_int			error;

	hdr17 = (struct ccb_hdr_0x17 *)addr;
	ccb = xpt_alloc_ccb();
	hdr = &ccb->ccb_h;

	hdr->pinfo = hdr17->pinfo;
	hdr->xpt_links = hdr17->xpt_links;
	hdr->sim_links = hdr17->sim_links;
	hdr->periph_links = hdr17->periph_links;
	hdr->retry_count = hdr17->retry_count;
	hdr->cbfcnp = hdr17->cbfcnp;
	hdr->func_code = hdr17->func_code;
	hdr->status = hdr17->status;
	hdr->path = hdr17->path;
	hdr->path_id = hdr17->path_id;
	hdr->target_id = hdr17->target_id;
	hdr->target_lun = hdr17->target_lun;
	hdr->flags = hdr17->flags;
	hdr->xflags = 0;
	hdr->periph_priv = hdr17->periph_priv;
	hdr->sim_priv = hdr17->sim_priv;
	hdr->timeout = hdr17->timeout;
	hdr->softtimeout.tv_sec = 0;
	hdr->softtimeout.tv_usec = 0;

	ccbb = (uint8_t *)&hdr[1];
	ccbb17 = (uint8_t *)&hdr17[1];
	if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) {
		struct ccb_trans_settings *cts;
		struct ccb_trans_settings_0x17 *cts17;

		cts = &ccb->cts;
		cts17 = (struct ccb_trans_settings_0x17 *)hdr17;
		cts->type = cts17->type;
		cts->protocol = cts17->protocol;
		cts->protocol_version = cts17->protocol_version;
		cts->transport = cts17->transport;
		cts->transport_version = cts17->transport_version;
		bcopy(&cts17->proto_specific, &cts->proto_specific,
		    sizeof(cts17->proto_specific));
		bcopy(&cts17->xport_specific, &cts->xport_specific,
		    sizeof(cts17->xport_specific));
	} else {
		bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN);
	}

	error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);

	hdr17->pinfo = hdr->pinfo;
	hdr17->xpt_links = hdr->xpt_links;
	hdr17->sim_links = hdr->sim_links;
	hdr17->periph_links = hdr->periph_links;
	hdr17->retry_count = hdr->retry_count;
	hdr17->cbfcnp = hdr->cbfcnp;
	hdr17->func_code = hdr->func_code;
	hdr17->status = hdr->status;
	hdr17->path = hdr->path;
	hdr17->path_id = hdr->path_id;
	hdr17->target_id = hdr->target_id;
	hdr17->target_lun = hdr->target_lun;
	hdr17->flags = hdr->flags;
	hdr17->periph_priv = hdr->periph_priv;
	hdr17->sim_priv = hdr->sim_priv;
	hdr17->timeout = hdr->timeout;

	if (ccb->ccb_h.func_code == XPT_PATH_INQ) {
		struct ccb_pathinq	*cpi;
		struct ccb_pathinq_0x17 *cpi17;

		/* The PATH_INQ only needs special handling on the way out */
		cpi = &ccb->cpi;
		cpi17 = (struct ccb_pathinq_0x17 *)hdr17;
		cpi17->version_num = cpi->version_num;
		cpi17->hba_inquiry = cpi->hba_inquiry;
		cpi17->target_sprt = (u_int8_t)cpi->target_sprt;
		cpi17->hba_misc = (u_int8_t)cpi->hba_misc;
		cpi17->hba_eng_cnt = cpi->hba_eng_cnt;
		bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN);
		cpi17->max_target = cpi->max_target;
		cpi17->max_lun = cpi->max_lun;
		cpi17->async_flags = cpi->async_flags;
		cpi17->hpath_id = cpi->hpath_id;
		cpi17->initiator_id = cpi->initiator_id;
		bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN);
		bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN);
		bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN);
		cpi17->unit_number = cpi->unit_number;
		cpi17->bus_id = cpi->bus_id;
		cpi17->base_transfer_speed = cpi->base_transfer_speed;
		cpi17->protocol = cpi->protocol;
		cpi17->protocol_version = cpi->protocol_version;
		cpi17->transport = cpi->transport;
		cpi17->transport_version = cpi->transport_version;
		bcopy(&cpi->xport_specific, &cpi17->xport_specific,
		    PATHINQ_SETTINGS_SIZE);
		cpi17->maxio = cpi->maxio;
		cpi17->hba_vendor = cpi->hba_vendor;
		cpi17->hba_device = cpi->hba_device;
		cpi17->hba_subvendor = cpi->hba_subvendor;
		cpi17->hba_subdevice = cpi->hba_subdevice;
	} else if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) {
		struct ccb_trans_settings *cts;
		struct ccb_trans_settings_0x17 *cts17;

		cts = &ccb->cts;
		cts17 = (struct ccb_trans_settings_0x17 *)hdr17;
		cts17->type = cts->type;
		cts17->protocol = cts->protocol;
		cts17->protocol_version = cts->protocol_version;
		cts17->transport = cts->transport;
		cts17->transport_version = cts->transport_version;
		bcopy(&cts->proto_specific, &cts17->proto_specific,
		    sizeof(cts17->proto_specific));
		bcopy(&cts->xport_specific, &cts17->xport_specific,
		    sizeof(cts17->xport_specific));
	} else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
		/* Copy the rest of the header over */
		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);

		cam_compat_translate_dev_match_0x18(ccb);
	} else {
		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
	}

	xpt_free_ccb(ccb);

	return (error);
}