]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/cam/cam_compat.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / cam / cam_compat.c
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$");
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
50 #include <cam/scsi/scsi_pass.h>
51
52 #include "opt_cam.h"
53
54 static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
55     int flag, struct thread *td, d_ioctl_t *cbfnp);
56
57 int
58 cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
59     struct thread *td, d_ioctl_t *cbfnp)
60 {
61         int error;
62
63         switch (cmd) {
64         case CAMIOCOMMAND_0x16:
65         {
66                 union ccb *ccb;
67
68                 ccb = (union ccb *)addr;
69                 if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS_0x16) {
70                         ccb->ccb_h.flags &= ~CAM_SG_LIST_PHYS_0x16;
71                         ccb->ccb_h.flags |= CAM_DATA_SG_PADDR;
72                 }
73                 if (ccb->ccb_h.flags & CAM_DATA_PHYS_0x16) {
74                         ccb->ccb_h.flags &= ~CAM_DATA_PHYS_0x16;
75                         ccb->ccb_h.flags |= CAM_DATA_PADDR;
76                 }
77                 if (ccb->ccb_h.flags & CAM_SCATTER_VALID_0x16) {
78                         ccb->ccb_h.flags &= CAM_SCATTER_VALID_0x16;
79                         ccb->ccb_h.flags |= CAM_DATA_SG;
80                 }
81                 cmd = CAMIOCOMMAND;
82                 error = (cbfnp)(dev, cmd, addr, flag, td);
83                 break;
84         }
85         case CAMGETPASSTHRU_0x16:
86                 cmd = CAMGETPASSTHRU;
87                 error = (cbfnp)(dev, cmd, addr, flag, td);
88                 break;
89         case CAMIOCOMMAND_0x17:
90                 cmd = CAMIOCOMMAND;
91                 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
92                 break;
93         case CAMGETPASSTHRU_0x17:
94                 cmd = CAMGETPASSTHRU;
95                 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
96                 break;
97         default:
98                 error = ENOTTY;
99         }
100
101         return (error);
102 }
103
104 static int
105 cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
106     struct thread *td, d_ioctl_t *cbfnp)
107 {
108         union ccb               *ccb;
109         struct ccb_hdr          *hdr;
110         struct ccb_hdr_0x17     *hdr17;
111         uint8_t                 *ccbb, *ccbb17;
112         u_int                   error;
113
114         hdr17 = (struct ccb_hdr_0x17 *)addr;
115         ccb = xpt_alloc_ccb();
116         hdr = &ccb->ccb_h;
117
118         hdr->pinfo = hdr17->pinfo;
119         hdr->xpt_links = hdr17->xpt_links;
120         hdr->sim_links = hdr17->sim_links;
121         hdr->periph_links = hdr17->periph_links;
122         hdr->retry_count = hdr17->retry_count;
123         hdr->cbfcnp = hdr17->cbfcnp;
124         hdr->func_code = hdr17->func_code;
125         hdr->status = hdr17->status;
126         hdr->path = hdr17->path;
127         hdr->path_id = hdr17->path_id;
128         hdr->target_id = hdr17->target_id;
129         hdr->target_lun = hdr17->target_lun;
130         hdr->ext_lun.lun64 = 0;
131         hdr->flags = hdr17->flags;
132         hdr->xflags = 0;
133         hdr->periph_priv = hdr17->periph_priv;
134         hdr->sim_priv = hdr17->sim_priv;
135         hdr->timeout = hdr17->timeout;
136         hdr->softtimeout.tv_sec = 0;
137         hdr->softtimeout.tv_usec = 0;
138
139         ccbb = (uint8_t *)&hdr[1];
140         ccbb17 = (uint8_t *)&hdr17[1];
141         bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN);
142
143         error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
144
145         hdr17->pinfo = hdr->pinfo;
146         hdr17->xpt_links = hdr->xpt_links;
147         hdr17->sim_links = hdr->sim_links;
148         hdr17->periph_links = hdr->periph_links;
149         hdr17->retry_count = hdr->retry_count;
150         hdr17->cbfcnp = hdr->cbfcnp;
151         hdr17->func_code = hdr->func_code;
152         hdr17->status = hdr->status;
153         hdr17->path = hdr->path;
154         hdr17->path_id = hdr->path_id;
155         hdr17->target_id = hdr->target_id;
156         hdr17->target_lun = hdr->target_lun;
157         hdr17->flags = hdr->flags;
158         hdr17->periph_priv = hdr->periph_priv;
159         hdr17->sim_priv = hdr->sim_priv;
160         hdr17->timeout = hdr->timeout;
161
162         /* The PATH_INQ only needs special handling on the way out */
163         if (ccb->ccb_h.func_code != XPT_PATH_INQ) {
164                 bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
165         } else {
166                 struct ccb_pathinq      *cpi;
167                 struct ccb_pathinq_0x17 *cpi17;
168
169                 cpi = &ccb->cpi;
170                 cpi17 = (struct ccb_pathinq_0x17 *)hdr17;
171                 cpi17->version_num = cpi->version_num;
172                 cpi17->hba_inquiry = cpi->hba_inquiry;
173                 cpi17->target_sprt = (u_int8_t)cpi->target_sprt;
174                 cpi17->hba_misc = (u_int8_t)cpi->hba_misc;
175                 cpi17->hba_eng_cnt = cpi->hba_eng_cnt;
176                 bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN);
177                 cpi17->max_target = cpi->max_target;
178                 cpi17->max_lun = cpi->max_lun;
179                 cpi17->async_flags = cpi->async_flags;
180                 cpi17->hpath_id = cpi->hpath_id;
181                 cpi17->initiator_id = cpi->initiator_id;
182                 bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN);
183                 bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN);
184                 bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN);
185                 cpi17->unit_number = cpi->unit_number;
186                 cpi17->bus_id = cpi->bus_id;
187                 cpi17->base_transfer_speed = cpi->base_transfer_speed;
188                 cpi17->protocol = cpi->protocol;
189                 cpi17->protocol_version = cpi->protocol_version;
190                 cpi17->transport = cpi->transport;
191                 cpi17->transport_version = cpi->transport_version;
192                 bcopy(&cpi->xport_specific, &cpi17->xport_specific,
193                     PATHINQ_SETTINGS_SIZE);
194                 cpi17->maxio = cpi->maxio;
195                 cpi17->hba_vendor = cpi->hba_vendor;
196                 cpi17->hba_device = cpi->hba_device;
197                 cpi17->hba_subvendor = cpi->hba_subvendor;
198                 cpi17->hba_subdevice = cpi->hba_subdevice;
199         }
200
201         xpt_free_ccb(ccb);
202
203         return (error);
204 }