The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cam/cam_compat.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * CAM ioctl compatibility shims
    3  *
    4  * Copyright (c) 2013 Scott Long
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions, and the following disclaimer,
   12  *    without modification, immediately at the beginning of the file.
   13  * 2. The name of the author may not be used to endorse or promote products
   14  *    derived from this software without specific prior written permission.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/11.1/sys/cam/cam_compat.c 307264 2016-10-14 06:56:06Z mav $");
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/types.h>
   36 #include <sys/kernel.h>
   37 #include <sys/conf.h>
   38 #include <sys/fcntl.h>
   39 
   40 #include <sys/lock.h>
   41 #include <sys/mutex.h>
   42 #include <sys/sysctl.h>
   43 #include <sys/kthread.h>
   44 
   45 #include <cam/cam.h>
   46 #include <cam/cam_ccb.h>
   47 #include <cam/cam_xpt.h>
   48 #include <cam/cam_compat.h>
   49 #include <cam/cam_periph.h>
   50 
   51 #include <cam/scsi/scsi_pass.h>
   52 
   53 #include "opt_cam.h"
   54 
   55 static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
   56     int flag, struct thread *td, d_ioctl_t *cbfnp);
   57 static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr,
   58     int flag, struct thread *td, d_ioctl_t *cbfnp);
   59 static int cam_compat_translate_dev_match_0x18(union ccb *ccb);
   60 
   61 int
   62 cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
   63     struct thread *td, d_ioctl_t *cbfnp)
   64 {
   65         int error;
   66 
   67         switch (cmd) {
   68         case CAMIOCOMMAND_0x16:
   69         {
   70                 struct ccb_hdr_0x17 *hdr17;
   71 
   72                 hdr17 = (struct ccb_hdr_0x17 *)addr;
   73                 if (hdr17->flags & CAM_SG_LIST_PHYS_0x16) {
   74                         hdr17->flags &= ~CAM_SG_LIST_PHYS_0x16;
   75                         hdr17->flags |= CAM_DATA_SG_PADDR;
   76                 }
   77                 if (hdr17->flags & CAM_DATA_PHYS_0x16) {
   78                         hdr17->flags &= ~CAM_DATA_PHYS_0x16;
   79                         hdr17->flags |= CAM_DATA_PADDR;
   80                 }
   81                 if (hdr17->flags & CAM_SCATTER_VALID_0x16) {
   82                         hdr17->flags &= CAM_SCATTER_VALID_0x16;
   83                         hdr17->flags |= CAM_DATA_SG;
   84                 }
   85                 cmd = CAMIOCOMMAND;
   86                 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
   87                 break;
   88         }
   89         case CAMGETPASSTHRU_0x16:
   90                 cmd = CAMGETPASSTHRU;
   91                 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
   92                 break;
   93         case CAMIOCOMMAND_0x17:
   94                 cmd = CAMIOCOMMAND;
   95                 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
   96                 break;
   97         case CAMGETPASSTHRU_0x17:
   98                 cmd = CAMGETPASSTHRU;
   99                 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
  100                 break;
  101         case CAMIOCOMMAND_0x18:
  102                 cmd = CAMIOCOMMAND;
  103                 error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
  104                 break;
  105         case CAMGETPASSTHRU_0x18:
  106                 cmd = CAMGETPASSTHRU;
  107                 error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
  108                 break;
  109         default:
  110                 error = ENOTTY;
  111         }
  112 
  113         return (error);
  114 }
  115 
  116 static int
  117 cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
  118     struct thread *td, d_ioctl_t *cbfnp)
  119 {
  120         union ccb               *ccb;
  121         struct ccb_hdr          *hdr;
  122         struct ccb_hdr_0x17     *hdr17;
  123         uint8_t                 *ccbb, *ccbb17;
  124         u_int                   error;
  125 
  126         hdr17 = (struct ccb_hdr_0x17 *)addr;
  127         ccb = xpt_alloc_ccb();
  128         hdr = &ccb->ccb_h;
  129 
  130         hdr->pinfo = hdr17->pinfo;
  131         hdr->xpt_links = hdr17->xpt_links;
  132         hdr->sim_links = hdr17->sim_links;
  133         hdr->periph_links = hdr17->periph_links;
  134         hdr->retry_count = hdr17->retry_count;
  135         hdr->cbfcnp = hdr17->cbfcnp;
  136         hdr->func_code = hdr17->func_code;
  137         hdr->status = hdr17->status;
  138         hdr->path = hdr17->path;
  139         hdr->path_id = hdr17->path_id;
  140         hdr->target_id = hdr17->target_id;
  141         hdr->target_lun = hdr17->target_lun;
  142         hdr->flags = hdr17->flags;
  143         hdr->xflags = 0;
  144         hdr->periph_priv = hdr17->periph_priv;
  145         hdr->sim_priv = hdr17->sim_priv;
  146         hdr->timeout = hdr17->timeout;
  147         hdr->softtimeout.tv_sec = 0;
  148         hdr->softtimeout.tv_usec = 0;
  149 
  150         ccbb = (uint8_t *)&hdr[1];
  151         ccbb17 = (uint8_t *)&hdr17[1];
  152         if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) {
  153                 struct ccb_trans_settings *cts;
  154                 struct ccb_trans_settings_0x17 *cts17;
  155 
  156                 cts = &ccb->cts;
  157                 cts17 = (struct ccb_trans_settings_0x17 *)hdr17;
  158                 cts->type = cts17->type;
  159                 cts->protocol = cts17->protocol;
  160                 cts->protocol_version = cts17->protocol_version;
  161                 cts->transport = cts17->transport;
  162                 cts->transport_version = cts17->transport_version;
  163                 bcopy(&cts17->proto_specific, &cts->proto_specific,
  164                     sizeof(cts17->proto_specific));
  165                 bcopy(&cts17->xport_specific, &cts->xport_specific,
  166                     sizeof(cts17->xport_specific));
  167         } else {
  168                 bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN);
  169         }
  170 
  171         error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
  172 
  173         hdr17->pinfo = hdr->pinfo;
  174         hdr17->xpt_links = hdr->xpt_links;
  175         hdr17->sim_links = hdr->sim_links;
  176         hdr17->periph_links = hdr->periph_links;
  177         hdr17->retry_count = hdr->retry_count;
  178         hdr17->cbfcnp = hdr->cbfcnp;
  179         hdr17->func_code = hdr->func_code;
  180         hdr17->status = hdr->status;
  181         hdr17->path = hdr->path;
  182         hdr17->path_id = hdr->path_id;
  183         hdr17->target_id = hdr->target_id;
  184         hdr17->target_lun = hdr->target_lun;
  185         hdr17->flags = hdr->flags;
  186         hdr17->periph_priv = hdr->periph_priv;
  187         hdr17->sim_priv = hdr->sim_priv;
  188         hdr17->timeout = hdr->timeout;
  189 
  190         if (ccb->ccb_h.func_code == XPT_PATH_INQ) {
  191                 struct ccb_pathinq      *cpi;
  192                 struct ccb_pathinq_0x17 *cpi17;
  193 
  194                 /* The PATH_INQ only needs special handling on the way out */
  195                 cpi = &ccb->cpi;
  196                 cpi17 = (struct ccb_pathinq_0x17 *)hdr17;
  197                 cpi17->version_num = cpi->version_num;
  198                 cpi17->hba_inquiry = cpi->hba_inquiry;
  199                 cpi17->target_sprt = (u_int8_t)cpi->target_sprt;
  200                 cpi17->hba_misc = (u_int8_t)cpi->hba_misc;
  201                 cpi17->hba_eng_cnt = cpi->hba_eng_cnt;
  202                 bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN);
  203                 cpi17->max_target = cpi->max_target;
  204                 cpi17->max_lun = cpi->max_lun;
  205                 cpi17->async_flags = cpi->async_flags;
  206                 cpi17->hpath_id = cpi->hpath_id;
  207                 cpi17->initiator_id = cpi->initiator_id;
  208                 bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN);
  209                 bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN);
  210                 bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN);
  211                 cpi17->unit_number = cpi->unit_number;
  212                 cpi17->bus_id = cpi->bus_id;
  213                 cpi17->base_transfer_speed = cpi->base_transfer_speed;
  214                 cpi17->protocol = cpi->protocol;
  215                 cpi17->protocol_version = cpi->protocol_version;
  216                 cpi17->transport = cpi->transport;
  217                 cpi17->transport_version = cpi->transport_version;
  218                 bcopy(&cpi->xport_specific, &cpi17->xport_specific,
  219                     PATHINQ_SETTINGS_SIZE);
  220                 cpi17->maxio = cpi->maxio;
  221                 cpi17->hba_vendor = cpi->hba_vendor;
  222                 cpi17->hba_device = cpi->hba_device;
  223                 cpi17->hba_subvendor = cpi->hba_subvendor;
  224                 cpi17->hba_subdevice = cpi->hba_subdevice;
  225         } else if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) {
  226                 struct ccb_trans_settings *cts;
  227                 struct ccb_trans_settings_0x17 *cts17;
  228 
  229                 cts = &ccb->cts;
  230                 cts17 = (struct ccb_trans_settings_0x17 *)hdr17;
  231                 cts17->type = cts->type;
  232                 cts17->protocol = cts->protocol;
  233                 cts17->protocol_version = cts->protocol_version;
  234                 cts17->transport = cts->transport;
  235                 cts17->transport_version = cts->transport_version;
  236                 bcopy(&cts->proto_specific, &cts17->proto_specific,
  237                     sizeof(cts17->proto_specific));
  238                 bcopy(&cts->xport_specific, &cts17->xport_specific,
  239                     sizeof(cts17->xport_specific));
  240         } else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
  241                 /* Copy the rest of the header over */
  242                 bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
  243 
  244                 cam_compat_translate_dev_match_0x18(ccb);
  245         } else {
  246                 bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
  247         }
  248 
  249         xpt_free_ccb(ccb);
  250 
  251         return (error);
  252 }
  253 
  254 static int
  255 cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
  256     struct thread *td, d_ioctl_t *cbfnp)
  257 {
  258         union ccb               *ccb;
  259         struct ccb_hdr          *hdr;
  260         struct ccb_hdr_0x18     *hdr18;
  261         uint8_t                 *ccbb, *ccbb18;
  262         u_int                   error;
  263 
  264         hdr18 = (struct ccb_hdr_0x18 *)addr;
  265         ccb = xpt_alloc_ccb();
  266         hdr = &ccb->ccb_h;
  267 
  268         hdr->pinfo = hdr18->pinfo;
  269         hdr->xpt_links = hdr18->xpt_links;
  270         hdr->sim_links = hdr18->sim_links;
  271         hdr->periph_links = hdr18->periph_links;
  272         hdr->retry_count = hdr18->retry_count;
  273         hdr->cbfcnp = hdr18->cbfcnp;
  274         hdr->func_code = hdr18->func_code;
  275         hdr->status = hdr18->status;
  276         hdr->path = hdr18->path;
  277         hdr->path_id = hdr18->path_id;
  278         hdr->target_id = hdr18->target_id;
  279         hdr->target_lun = hdr18->target_lun;
  280         if (hdr18->xflags & CAM_EXTLUN_VALID_0x18)
  281                 hdr->target_lun = hdr18->ext_lun;
  282         hdr->flags = hdr18->flags;
  283         hdr->xflags = hdr18->xflags;
  284         hdr->periph_priv = hdr18->periph_priv;
  285         hdr->sim_priv = hdr18->sim_priv;
  286         hdr->timeout = hdr18->timeout;
  287         hdr->softtimeout.tv_sec = 0;
  288         hdr->softtimeout.tv_usec = 0;
  289 
  290         ccbb = (uint8_t *)&hdr[1];
  291         ccbb18 = (uint8_t *)&hdr18[1];
  292         if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) {
  293                 struct ccb_trans_settings *cts;
  294                 struct ccb_trans_settings_0x18 *cts18;
  295 
  296                 cts = &ccb->cts;
  297                 cts18 = (struct ccb_trans_settings_0x18 *)hdr18;
  298                 cts->type = cts18->type;
  299                 cts->protocol = cts18->protocol;
  300                 cts->protocol_version = cts18->protocol_version;
  301                 cts->transport = cts18->transport;
  302                 cts->transport_version = cts18->transport_version;
  303                 bcopy(&cts18->proto_specific, &cts->proto_specific,
  304                     sizeof(cts18->proto_specific));
  305                 bcopy(&cts18->xport_specific, &cts->xport_specific,
  306                     sizeof(cts18->xport_specific));
  307         } else {
  308                 bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN);
  309         }
  310 
  311         error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
  312 
  313         hdr18->pinfo = hdr->pinfo;
  314         hdr18->xpt_links = hdr->xpt_links;
  315         hdr18->sim_links = hdr->sim_links;
  316         hdr18->periph_links = hdr->periph_links;
  317         hdr18->retry_count = hdr->retry_count;
  318         hdr18->cbfcnp = hdr->cbfcnp;
  319         hdr18->func_code = hdr->func_code;
  320         hdr18->status = hdr->status;
  321         hdr18->path = hdr->path;
  322         hdr18->path_id = hdr->path_id;
  323         hdr18->target_id = hdr->target_id;
  324         hdr18->target_lun = hdr->target_lun;
  325         hdr18->ext_lun = hdr->target_lun;
  326         hdr18->flags = hdr->flags;
  327         hdr18->xflags = hdr->xflags | CAM_EXTLUN_VALID_0x18;
  328         hdr18->periph_priv = hdr->periph_priv;
  329         hdr18->sim_priv = hdr->sim_priv;
  330         hdr18->timeout = hdr->timeout;
  331 
  332         if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) {
  333                 struct ccb_trans_settings *cts;
  334                 struct ccb_trans_settings_0x18 *cts18;
  335 
  336                 cts = &ccb->cts;
  337                 cts18 = (struct ccb_trans_settings_0x18 *)hdr18;
  338                 cts18->type = cts->type;
  339                 cts18->protocol = cts->protocol;
  340                 cts18->protocol_version = cts->protocol_version;
  341                 cts18->transport = cts->transport;
  342                 cts18->transport_version = cts->transport_version;
  343                 bcopy(&cts->proto_specific, &cts18->proto_specific,
  344                     sizeof(cts18->proto_specific));
  345                 bcopy(&cts->xport_specific, &cts18->xport_specific,
  346                     sizeof(cts18->xport_specific));
  347         } else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
  348                 bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
  349                 cam_compat_translate_dev_match_0x18(ccb);
  350         } else {
  351                 bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
  352         }
  353 
  354         xpt_free_ccb(ccb);
  355 
  356         return (error);
  357 }
  358 
  359 static int
  360 cam_compat_translate_dev_match_0x18(union ccb *ccb)
  361 {
  362         struct dev_match_result         *dm;
  363         struct dev_match_result_0x18    *dm18;
  364         struct cam_periph_map_info      mapinfo;
  365         int i;
  366 
  367         /* Remap the CCB into kernel address space */
  368         bzero(&mapinfo, sizeof(mapinfo));
  369         cam_periph_mapmem(ccb, &mapinfo, MAXPHYS);
  370 
  371         dm = ccb->cdm.matches;
  372         /* Translate in-place: old fields are smaller */
  373         dm18 = (struct dev_match_result_0x18 *)(dm);
  374         
  375         for (i = 0; i < ccb->cdm.num_matches; i++) {
  376                 dm18[i].type = dm[i].type;
  377                 switch (dm[i].type) {
  378                 case DEV_MATCH_PERIPH:
  379                         memcpy(&dm18[i].result.periph_result.periph_name, 
  380                             &dm[i].result.periph_result.periph_name,
  381                             DEV_IDLEN);
  382                         dm18[i].result.periph_result.unit_number =
  383                            dm[i].result.periph_result.unit_number;
  384                         dm18[i].result.periph_result.path_id =
  385                            dm[i].result.periph_result.path_id;
  386                         dm18[i].result.periph_result.target_id =
  387                            dm[i].result.periph_result.target_id;
  388                         dm18[i].result.periph_result.target_lun =
  389                            dm[i].result.periph_result.target_lun;
  390                         break;
  391                 case DEV_MATCH_DEVICE:
  392                         dm18[i].result.device_result.path_id =
  393                            dm[i].result.device_result.path_id;
  394                         dm18[i].result.device_result.target_id =
  395                            dm[i].result.device_result.target_id;
  396                         dm18[i].result.device_result.target_lun =
  397                            dm[i].result.device_result.target_lun;
  398                         dm18[i].result.device_result.protocol =
  399                            dm[i].result.device_result.protocol;
  400                         memcpy(&dm18[i].result.device_result.inq_data, 
  401                             &dm[i].result.device_result.inq_data,
  402                             sizeof(struct scsi_inquiry_data));
  403                         memcpy(&dm18[i].result.device_result.ident_data,
  404                             &dm[i].result.device_result.ident_data,
  405                             sizeof(struct ata_params));
  406                         dm18[i].result.device_result.flags =
  407                            dm[i].result.device_result.flags;
  408                         break;
  409                 case DEV_MATCH_BUS:
  410                         memcpy(&dm18[i].result.bus_result, 
  411                             &dm[i].result.bus_result,
  412                             sizeof(struct bus_match_result));
  413                         break;
  414                 }
  415         }
  416 
  417         cam_periph_unmapmem(ccb, &mapinfo);
  418 
  419         return (0);
  420 }
  421 

Cache object: 6f8c8a7e3be651007ca1e12a09e16aa3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.