.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Changes: |
---|
3 | 4 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 08/23/2000 |
---|
.. | .. |
---|
116 | 117 | case NOT_READY: /* This happens if there is no disc in drive */ |
---|
117 | 118 | if (sdev->removable) |
---|
118 | 119 | break; |
---|
119 | | - /* FALLTHROUGH */ |
---|
| 120 | + fallthrough; |
---|
120 | 121 | case UNIT_ATTENTION: |
---|
121 | 122 | if (sdev->removable) { |
---|
122 | 123 | sdev->changed = 1; |
---|
123 | 124 | result = 0; /* This is no longer considered an error */ |
---|
124 | 125 | break; |
---|
125 | 126 | } |
---|
126 | | - /* FALLTHROUGH -- for non-removable media */ |
---|
| 127 | + fallthrough; /* for non-removable media */ |
---|
127 | 128 | default: |
---|
128 | 129 | sdev_printk(KERN_INFO, sdev, |
---|
129 | 130 | "ioctl_internal_command return code = %x\n", |
---|
.. | .. |
---|
188 | 189 | } |
---|
189 | 190 | |
---|
190 | 191 | |
---|
191 | | -/** |
---|
192 | | - * scsi_ioctl - Dispatch ioctl to scsi device |
---|
193 | | - * @sdev: scsi device receiving ioctl |
---|
194 | | - * @cmd: which ioctl is it |
---|
195 | | - * @arg: data associated with ioctl |
---|
196 | | - * |
---|
197 | | - * Description: The scsi_ioctl() function differs from most ioctls in that it |
---|
198 | | - * does not take a major/minor number as the dev field. Rather, it takes |
---|
199 | | - * a pointer to a &struct scsi_device. |
---|
200 | | - */ |
---|
201 | | -int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) |
---|
| 192 | +static int scsi_ioctl_common(struct scsi_device *sdev, int cmd, void __user *arg) |
---|
202 | 193 | { |
---|
203 | 194 | char scsi_cmd[MAX_COMMAND_SIZE]; |
---|
204 | 195 | struct scsi_sense_hdr sense_hdr; |
---|
.. | .. |
---|
220 | 211 | } |
---|
221 | 212 | |
---|
222 | 213 | switch (cmd) { |
---|
223 | | - case SCSI_IOCTL_GET_IDLUN: |
---|
224 | | - if (!access_ok(VERIFY_WRITE, arg, sizeof(struct scsi_idlun))) |
---|
| 214 | + case SCSI_IOCTL_GET_IDLUN: { |
---|
| 215 | + struct scsi_idlun v = { |
---|
| 216 | + .dev_id = (sdev->id & 0xff) |
---|
| 217 | + + ((sdev->lun & 0xff) << 8) |
---|
| 218 | + + ((sdev->channel & 0xff) << 16) |
---|
| 219 | + + ((sdev->host->host_no & 0xff) << 24), |
---|
| 220 | + .host_unique_id = sdev->host->unique_id |
---|
| 221 | + }; |
---|
| 222 | + if (copy_to_user(arg, &v, sizeof(struct scsi_idlun))) |
---|
225 | 223 | return -EFAULT; |
---|
226 | | - |
---|
227 | | - __put_user((sdev->id & 0xff) |
---|
228 | | - + ((sdev->lun & 0xff) << 8) |
---|
229 | | - + ((sdev->channel & 0xff) << 16) |
---|
230 | | - + ((sdev->host->host_no & 0xff) << 24), |
---|
231 | | - &((struct scsi_idlun __user *)arg)->dev_id); |
---|
232 | | - __put_user(sdev->host->unique_id, |
---|
233 | | - &((struct scsi_idlun __user *)arg)->host_unique_id); |
---|
234 | 224 | return 0; |
---|
| 225 | + } |
---|
235 | 226 | case SCSI_IOCTL_GET_BUS_NUMBER: |
---|
236 | 227 | return put_user(sdev->host->host_no, (int __user *)arg); |
---|
237 | 228 | case SCSI_IOCTL_PROBE_HOST: |
---|
.. | .. |
---|
265 | 256 | return scsi_ioctl_get_pci(sdev, arg); |
---|
266 | 257 | case SG_SCSI_RESET: |
---|
267 | 258 | return scsi_ioctl_reset(sdev, arg); |
---|
268 | | - default: |
---|
269 | | - if (sdev->host->hostt->ioctl) |
---|
270 | | - return sdev->host->hostt->ioctl(sdev, cmd, arg); |
---|
271 | 259 | } |
---|
| 260 | + return -ENOIOCTLCMD; |
---|
| 261 | +} |
---|
| 262 | + |
---|
| 263 | +/** |
---|
| 264 | + * scsi_ioctl - Dispatch ioctl to scsi device |
---|
| 265 | + * @sdev: scsi device receiving ioctl |
---|
| 266 | + * @cmd: which ioctl is it |
---|
| 267 | + * @arg: data associated with ioctl |
---|
| 268 | + * |
---|
| 269 | + * Description: The scsi_ioctl() function differs from most ioctls in that it |
---|
| 270 | + * does not take a major/minor number as the dev field. Rather, it takes |
---|
| 271 | + * a pointer to a &struct scsi_device. |
---|
| 272 | + */ |
---|
| 273 | +int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) |
---|
| 274 | +{ |
---|
| 275 | + int ret = scsi_ioctl_common(sdev, cmd, arg); |
---|
| 276 | + |
---|
| 277 | + if (ret != -ENOIOCTLCMD) |
---|
| 278 | + return ret; |
---|
| 279 | + |
---|
| 280 | + if (sdev->host->hostt->ioctl) |
---|
| 281 | + return sdev->host->hostt->ioctl(sdev, cmd, arg); |
---|
| 282 | + |
---|
272 | 283 | return -EINVAL; |
---|
273 | 284 | } |
---|
274 | 285 | EXPORT_SYMBOL(scsi_ioctl); |
---|
275 | 286 | |
---|
| 287 | +#ifdef CONFIG_COMPAT |
---|
| 288 | +int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) |
---|
| 289 | +{ |
---|
| 290 | + int ret = scsi_ioctl_common(sdev, cmd, arg); |
---|
| 291 | + |
---|
| 292 | + if (ret != -ENOIOCTLCMD) |
---|
| 293 | + return ret; |
---|
| 294 | + |
---|
| 295 | + if (sdev->host->hostt->compat_ioctl) |
---|
| 296 | + return sdev->host->hostt->compat_ioctl(sdev, cmd, arg); |
---|
| 297 | + |
---|
| 298 | + return ret; |
---|
| 299 | +} |
---|
| 300 | +EXPORT_SYMBOL(scsi_compat_ioctl); |
---|
| 301 | +#endif |
---|
| 302 | + |
---|
276 | 303 | /* |
---|
277 | 304 | * We can process a reset even when a device isn't fully operable. |
---|
278 | 305 | */ |
---|