summaryrefslogtreecommitdiffstats
path: root/sys/cam/cam_compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam/cam_compat.c')
-rw-r--r--sys/cam/cam_compat.c129
1 files changed, 122 insertions, 7 deletions
diff --git a/sys/cam/cam_compat.c b/sys/cam/cam_compat.c
index a24debc..f291479 100644
--- a/sys/cam/cam_compat.c
+++ b/sys/cam/cam_compat.c
@@ -44,23 +44,28 @@ __FBSDID("$FreeBSD$");
#include <cam/cam.h>
#include <cam/cam_ccb.h>
+#include <cam/cam_xpt.h>
#include <cam/cam_compat.h>
#include <cam/scsi/scsi_pass.h>
#include "opt_cam.h"
+static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
+ int flag, struct thread *td, d_ioctl_t *cbfnp);
+
int
-cam_compat_ioctl(struct cdev *dev, u_long *cmd, caddr_t *addr, int *flag, struct thread *td)
+cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
+ struct thread *td, d_ioctl_t *cbfnp)
{
int error;
- switch (*cmd) {
+ switch (cmd) {
case CAMIOCOMMAND_0x16:
{
union ccb *ccb;
- ccb = (union ccb *)*addr;
+ ccb = (union ccb *)addr;
if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS_0x16) {
ccb->ccb_h.flags &= ~CAM_SG_LIST_PHYS_0x16;
ccb->ccb_h.flags |= CAM_DATA_SG_PADDR;
@@ -73,13 +78,21 @@ cam_compat_ioctl(struct cdev *dev, u_long *cmd, caddr_t *addr, int *flag, struct
ccb->ccb_h.flags &= CAM_SCATTER_VALID_0x16;
ccb->ccb_h.flags |= CAM_DATA_SG;
}
- *cmd = CAMIOCOMMAND;
- error = EAGAIN;
+ cmd = CAMIOCOMMAND;
+ error = (cbfnp)(dev, cmd, addr, flag, td);
break;
}
case CAMGETPASSTHRU_0x16:
- *cmd = CAMGETPASSTHRU;
- error = EAGAIN;
+ cmd = CAMGETPASSTHRU;
+ error = (cbfnp)(dev, cmd, addr, flag, td);
+ break;
+ case CAMIOCOMMAND_0x17:
+ cmd = CAMIOCOMMAND;
+ error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
+ break;
+ case CAMGETPASSTHRU_0x17:
+ cmd = CAMGETPASSTHRU;
+ error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
break;
default:
error = ENOTTY;
@@ -87,3 +100,105 @@ cam_compat_ioctl(struct cdev *dev, u_long *cmd, caddr_t *addr, int *flag, struct
return (error);
}
+
+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->ext_lun.lun64 = 0;
+ 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];
+ 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;
+
+ /* The PATH_INQ only needs special handling on the way out */
+ if (ccb->ccb_h.func_code != XPT_PATH_INQ) {
+ bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
+ } else {
+ struct ccb_pathinq *cpi;
+ struct ccb_pathinq_0x17 *cpi17;
+
+ 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;
+ }
+
+ xpt_free_ccb(ccb);
+
+ return (error);
+}
OpenPOWER on IntegriCloud