예제 #1
0
/*
 * Compose a SMP DISCOVER request and put it into a CCB.  This is current
 * as of SPL Revision 7.
 */
void
smp_discover(struct ccb_smpio *smpio, uint32_t retries,
	     void (*cbfcnp)(struct cam_periph *, union ccb *),
	     struct smp_discover_request *request, int request_len,
	     uint8_t *response, int response_len, int long_response,
	     int ignore_zone_group, int phy, uint32_t timeout)
{
	cam_fill_smpio(smpio,
		       retries,
		       cbfcnp,
		       /*flags*/CAM_DIR_BOTH,
		       (uint8_t *)request,
		       request_len - SMP_CRC_LEN,
		       response,
		       response_len,
		       timeout);

	bzero(request, sizeof(*request));
	request->frame_type = SMP_FRAME_TYPE_REQUEST;
	request->function = SMP_FUNC_DISCOVER;
	request->response_len = long_response ? SMP_DIS_RESPONSE_LEN : 0;
	request->request_len = long_response ? SMP_DIS_REQUEST_LEN : 0;
	if (ignore_zone_group != 0)
		request->ignore_zone_group |= SMP_DIS_IGNORE_ZONE_GROUP;
	request->phy = phy;
}
예제 #2
0
/*
 * Compose a SMP PHY CONTROL request and put it into a CCB.  This is
 * current as of SPL Revision 7.
 */
void
smp_phy_control(struct ccb_smpio *smpio, uint32_t retries,
		void (*cbfcnp)(struct cam_periph *, union ccb *),
		struct smp_phy_control_request *request, int request_len,
		uint8_t *response, int response_len, int long_response,
		uint32_t expected_exp_change_count, int phy, int phy_op,
		int update_pp_timeout_val, uint64_t attached_device_name,
		int prog_min_prl, int prog_max_prl, int slumber_partial,
		int pp_timeout_value, uint32_t timeout)
{
	cam_fill_smpio(smpio,
		       retries,
		       cbfcnp,
		       /*flags*/CAM_DIR_BOTH,
		       (uint8_t *)request,
		       request_len - SMP_CRC_LEN,
		       response,
		       response_len,
		       timeout);

	bzero(request, sizeof(*request));

	request->frame_type = SMP_FRAME_TYPE_REQUEST;
	request->function = SMP_FUNC_PHY_CONTROL;
	request->response_len = long_response ? SMP_PC_RESPONSE_LEN : 0;
	request->request_len = long_response ? SMP_PC_REQUEST_LEN : 0;
	scsi_ulto2b(expected_exp_change_count, request->expected_exp_chg_cnt);
	request->phy = phy;
	request->phy_operation = phy_op;

	if (update_pp_timeout_val != 0)
		request->update_pp_timeout |= SMP_PC_UPDATE_PP_TIMEOUT;

	scsi_u64to8b(attached_device_name, request->attached_device_name);
	request->prog_min_phys_link_rate = (prog_min_prl <<
		SMP_PC_PROG_MIN_PL_RATE_SHIFT) & SMP_PC_PROG_MIN_PL_RATE_MASK;
	request->prog_max_phys_link_rate = (prog_max_prl <<
		SMP_PC_PROG_MAX_PL_RATE_SHIFT) & SMP_PC_PROG_MAX_PL_RATE_MASK;
	request->config_bits0 = slumber_partial;
	request->pp_timeout_value = pp_timeout_value;
}
예제 #3
0
/*
 * Compose a SMP REPORT MANUFACTURER INFORMATION request and put it into a
 * CCB.  This is current as of SPL Revision 7.
 */
void
smp_report_manuf_info(struct ccb_smpio *smpio, uint32_t retries,
		      void (*cbfcnp)(struct cam_periph *, union ccb *),
		      struct smp_report_manuf_info_request *request,
		      int request_len, uint8_t *response, int response_len,
		      int long_response, uint32_t timeout)
{
	cam_fill_smpio(smpio,
		       retries,
		       cbfcnp,
		       /*flags*/CAM_DIR_BOTH,
		       (uint8_t *)request,
		       request_len - SMP_CRC_LEN,
		       response,
		       response_len,
		       timeout);

	bzero(request, sizeof(*request));

	request->frame_type = SMP_FRAME_TYPE_REQUEST;
	request->function = SMP_FUNC_REPORT_MANUF_INFO;
	request->response_len = long_response ? SMP_RMI_RESPONSE_LEN : 0;
	request->request_len = long_response ? SMP_RMI_REQUEST_LEN : 0;
}
예제 #4
0
파일: smp_fre_cam.c 프로젝트: fortsage/nio
int
smp_send_req(const struct smp_target_obj * tobj, struct smp_req_resp * rresp,
             int verbose)
{
    union ccb *ccb;
    struct tobj_cam_t * tcp;
    int retval, emsk;
    int flags = 0;

    if ((NULL == tobj) || (0 == tobj->opened) || (NULL == tobj->vp)) {
        if (verbose)
            fprintf(stderr, "smp_send_req: nothing open??\n");
        return -1;
    }
    if (I_CAM != tobj->interface_selector) {
        fprintf(stderr, "smp_send_req: unknown transport [%d]\n",
                tobj->interface_selector);
        return -1;
    }
    tcp = (struct tobj_cam_t *)tobj->vp;
    if (! (ccb = cam_getccb(tcp->cam_dev))) {
        fprintf(stderr, "cam_getccb: failed\n");
        return -1;
    }

    // clear out structure, except for header that was filled in for us
    bzero(&(&ccb->ccb_h)[1],
            sizeof(union ccb) - sizeof(struct ccb_hdr));

    flags |= CAM_DEV_QFRZDIS;
    /* CAM does not want request_len including CRC */
    cam_fill_smpio(&ccb->smpio,
                   /*retries*/ 2,       /* guess */
                   /*cbfcnp*/ NULL,
                   /*flags*/ flags,
                   /*smp_request*/ rresp->request,
                   /*smp_request_len*/ rresp->request_len - 4,
                   /*smp_response*/ rresp->response,
                   /*smp_response_len*/ rresp->max_response_len,
                   /*timeout*/ 5000);   /* milliseconds ? */

    ccb->smpio.flags = SMP_FLAG_NONE;

    emsk = 0;
    if (((retval = cam_send_ccb(tcp->cam_dev, ccb)) < 0) ||
        ((((emsk = (ccb->ccb_h.status & CAM_STATUS_MASK))) != CAM_REQ_CMP) &&
         (emsk != CAM_SMP_STATUS_ERROR))) {
        cam_error_print(tcp->cam_dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
        cam_freeccb(ccb);
        return -1;
    }
    if (((emsk == CAM_REQ_CMP) || (emsk == CAM_SMP_STATUS_ERROR)) &&
        (rresp->max_response_len > 0)) {
        if ((emsk == CAM_SMP_STATUS_ERROR) && (verbose > 3))
            cam_error_print(tcp->cam_dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL,
                            stderr);
        rresp->act_response_len = -1;
        cam_freeccb(ccb);
        return 0;
    } else {
        fprintf(stderr, "smp_send_req(cam): not sure how it got here\n");
        cam_freeccb(ccb);
        return emsk ? emsk : -1;
    }
}