diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_cfdc.c')
| -rw-r--r-- | drivers/s390/scsi/zfcp_cfdc.c | 259 |
1 files changed, 0 insertions, 259 deletions
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c deleted file mode 100644 index ec2abceca6d..00000000000 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * zfcp device driver - * - * Userspace interface for accessing the - * Access Control Lists / Control File Data Channel - * - * Copyright IBM Corporation 2008 - */ - -#include <linux/types.h> -#include <linux/miscdevice.h> -#include <asm/ccwdev.h> -#include "zfcp_def.h" -#include "zfcp_ext.h" -#include "zfcp_fsf.h" - -#define ZFCP_CFDC_CMND_DOWNLOAD_NORMAL 0x00010001 -#define ZFCP_CFDC_CMND_DOWNLOAD_FORCE 0x00010101 -#define ZFCP_CFDC_CMND_FULL_ACCESS 0x00000201 -#define ZFCP_CFDC_CMND_RESTRICTED_ACCESS 0x00000401 -#define ZFCP_CFDC_CMND_UPLOAD 0x00010002 - -#define ZFCP_CFDC_DOWNLOAD 0x00000001 -#define ZFCP_CFDC_UPLOAD 0x00000002 -#define ZFCP_CFDC_WITH_CONTROL_FILE 0x00010000 - -#define ZFCP_CFDC_IOC_MAGIC 0xDD -#define ZFCP_CFDC_IOC \ - _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_data) - -/** - * struct zfcp_cfdc_data - data for ioctl cfdc interface - * @signature: request signature - * @devno: FCP adapter device number - * @command: command code - * @fsf_status: returns status of FSF command to userspace - * @fsf_status_qual: returned to userspace - * @payloads: access conflicts list - * @control_file: access control table - */ -struct zfcp_cfdc_data { - u32 signature; - u32 devno; - u32 command; - u32 fsf_status; - u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; - u8 payloads[256]; - u8 control_file[0]; -}; - -static int zfcp_cfdc_copy_from_user(struct scatterlist *sg, - void __user *user_buffer) -{ - unsigned int length; - unsigned int size = ZFCP_CFDC_MAX_SIZE; - - while (size) { - length = min((unsigned int)size, sg->length); - if (copy_from_user(sg_virt(sg++), user_buffer, length)) - return -EFAULT; - user_buffer += length; - size -= length; - } - return 0; -} - -static int zfcp_cfdc_copy_to_user(void __user *user_buffer, - struct scatterlist *sg) -{ - unsigned int length; - unsigned int size = ZFCP_CFDC_MAX_SIZE; - - while (size) { - length = min((unsigned int) size, sg->length); - if (copy_to_user(user_buffer, sg_virt(sg++), length)) - return -EFAULT; - user_buffer += length; - size -= length; - } - return 0; -} - -static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) -{ - struct zfcp_adapter *adapter = NULL, *cur_adapter; - struct ccw_dev_id dev_id; - - read_lock_irq(&zfcp_data.config_lock); - list_for_each_entry(cur_adapter, &zfcp_data.adapter_list_head, list) { - ccw_device_get_id(cur_adapter->ccw_device, &dev_id); - if (dev_id.devno == devno) { - adapter = cur_adapter; - zfcp_adapter_get(adapter); - break; - } - } - read_unlock_irq(&zfcp_data.config_lock); - return adapter; -} - -static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) -{ - switch (command) { - case ZFCP_CFDC_CMND_DOWNLOAD_NORMAL: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_NORMAL_MODE; - break; - case ZFCP_CFDC_CMND_DOWNLOAD_FORCE: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_FORCE; - break; - case ZFCP_CFDC_CMND_FULL_ACCESS: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_FULL_ACCESS; - break; - case ZFCP_CFDC_CMND_RESTRICTED_ACCESS: - fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; - fsf_cfdc->option = FSF_CFDC_OPTION_RESTRICTED_ACCESS; - break; - case ZFCP_CFDC_CMND_UPLOAD: - fsf_cfdc->command = FSF_QTCB_UPLOAD_CONTROL_FILE; - fsf_cfdc->option = 0; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int zfcp_cfdc_sg_setup(int command, struct scatterlist *sg, - u8 __user *control_file) -{ - int retval; - retval = zfcp_sg_setup_table(sg, ZFCP_CFDC_PAGES); - if (retval) - return retval; - - sg[ZFCP_CFDC_PAGES - 1].length = ZFCP_CFDC_MAX_SIZE % PAGE_SIZE; - - if (command & ZFCP_CFDC_WITH_CONTROL_FILE && - command & ZFCP_CFDC_DOWNLOAD) { - retval = zfcp_cfdc_copy_from_user(sg, control_file); - if (retval) { - zfcp_sg_free_table(sg, ZFCP_CFDC_PAGES); - return -EFAULT; - } - } - - return 0; -} - -static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data, - struct zfcp_fsf_req *req) -{ - data->fsf_status = req->qtcb->header.fsf_status; - memcpy(&data->fsf_status_qual, &req->qtcb->header.fsf_status_qual, - sizeof(union fsf_status_qual)); - memcpy(&data->payloads, &req->qtcb->bottom.support.els, - sizeof(req->qtcb->bottom.support.els)); -} - -static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, - unsigned long buffer) -{ - struct zfcp_cfdc_data *data; - struct zfcp_cfdc_data __user *data_user; - struct zfcp_adapter *adapter; - struct zfcp_fsf_req *req; - struct zfcp_fsf_cfdc *fsf_cfdc; - int retval; - - if (command != ZFCP_CFDC_IOC) - return -ENOTTY; - - data_user = (void __user *) buffer; - if (!data_user) - return -EINVAL; - - fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL); - if (!fsf_cfdc) - return -ENOMEM; - - data = kmalloc(sizeof(struct zfcp_cfdc_data), GFP_KERNEL); - if (!data) { - retval = -ENOMEM; - goto no_mem_sense; - } - - retval = copy_from_user(data, data_user, sizeof(*data)); - if (retval) { - retval = -EFAULT; - goto free_buffer; - } - - if (data->signature != 0xCFDCACDF) { - retval = -EINVAL; - goto free_buffer; - } - - retval = zfcp_cfdc_set_fsf(fsf_cfdc, data->command); - - adapter = zfcp_cfdc_get_adapter(data->devno); - if (!adapter) { - retval = -ENXIO; - goto free_buffer; - } - - retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg, - data_user->control_file); - if (retval) - goto adapter_put; - req = zfcp_fsf_control_file(adapter, fsf_cfdc); - if (IS_ERR(req)) { - retval = PTR_ERR(req); - goto free_sg; - } - - if (req->status & ZFCP_STATUS_FSFREQ_ERROR) { - retval = -ENXIO; - goto free_fsf; - } - - zfcp_cfdc_req_to_sense(data, req); - retval = copy_to_user(data_user, data, sizeof(*data_user)); - if (retval) { - retval = -EFAULT; - goto free_fsf; - } - - if (data->command & ZFCP_CFDC_UPLOAD) - retval = zfcp_cfdc_copy_to_user(&data_user->control_file, - fsf_cfdc->sg); - - free_fsf: - zfcp_fsf_req_free(req); - free_sg: - zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES); - adapter_put: - zfcp_adapter_put(adapter); - free_buffer: - kfree(data); - no_mem_sense: - kfree(fsf_cfdc); - return retval; -} - -static const struct file_operations zfcp_cfdc_fops = { - .unlocked_ioctl = zfcp_cfdc_dev_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = zfcp_cfdc_dev_ioctl -#endif -}; - -struct miscdevice zfcp_cfdc_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "zfcp_cfdc", - .fops = &zfcp_cfdc_fops, -}; |
