X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fscsi%2Fzfcp_aux.c;h=007f915973b71fafb0b55fa982fe691debf2ef22;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=88414579d6394733463e5018b032f80215065d60;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 88414579d..007f91597 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -12,6 +12,7 @@ * Wolfgang Taphorn * Stefan Bader * Heiko Carstens + * Andreas Herrmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,8 +29,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* this drivers version (do not edit !!! generated and updated by cvs) */ -#define ZFCP_AUX_REVISION "$Revision: 1.129 $" +#define ZFCP_AUX_REVISION "$Revision: 1.145 $" #include "zfcp_ext.h" @@ -45,7 +45,6 @@ static int __init zfcp_module_init(void); static void zfcp_ns_gid_pn_handler(unsigned long); /* miscellaneous */ - static inline int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t); static inline void zfcp_sg_list_free(struct zfcp_sg_list *); static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *, @@ -60,7 +59,7 @@ static int zfcp_cfdc_dev_ioctl(struct inode *, struct file *, #define ZFCP_CFDC_IOC \ _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_sense_data) -#ifdef CONFIG_S390_SUPPORT +#ifdef CONFIG_COMPAT static struct ioctl_trans zfcp_ioctl_trans = {ZFCP_CFDC_IOC, (void*) sys_ioctl}; #endif @@ -80,6 +79,7 @@ static struct miscdevice zfcp_cfdc_misc = { module_init(zfcp_module_init); MODULE_AUTHOR("Heiko Carstens , " + "Andreas Herrman , " "Martin Peschke , " "Raimund Schroeder , " "Wolfgang Taphorn , " @@ -145,7 +145,7 @@ zfcp_cmd_dbf_event_fsf(const char *text, struct zfcp_fsf_req *fsf_req, int i; unsigned long flags; - write_lock_irqsave(&adapter->cmd_dbf_lock, flags); + spin_lock_irqsave(&adapter->dbf_lock, flags); if (zfcp_fsf_req_is_scsi_cmnd(fsf_req)) { scsi_cmnd = fsf_req->data.send_fcp_command_task.scsi_cmnd; debug_text_event(adapter->cmd_dbf, level, "fsferror"); @@ -164,7 +164,7 @@ zfcp_cmd_dbf_event_fsf(const char *text, struct zfcp_fsf_req *fsf_req, (char *) add_data + i, min(ZFCP_CMD_DBF_LENGTH, add_length - i)); } - write_unlock_irqrestore(&adapter->cmd_dbf_lock, flags); + spin_unlock_irqrestore(&adapter->dbf_lock, flags); } /* XXX additionally log unit if available */ @@ -181,7 +181,7 @@ zfcp_cmd_dbf_event_scsi(const char *text, struct scsi_cmnd *scsi_cmnd) adapter = (struct zfcp_adapter *) scsi_cmnd->device->host->hostdata[0]; req_data = (union zfcp_req_data *) scsi_cmnd->host_scribble; fsf_req = (req_data ? req_data->send_fcp_command_task.fsf_req : NULL); - write_lock_irqsave(&adapter->cmd_dbf_lock, flags); + spin_lock_irqsave(&adapter->dbf_lock, flags); debug_text_event(adapter->cmd_dbf, level, "hostbyte"); debug_text_event(adapter->cmd_dbf, level, text); debug_event(adapter->cmd_dbf, level, &scsi_cmnd->result, sizeof (u32)); @@ -198,7 +198,7 @@ zfcp_cmd_dbf_event_scsi(const char *text, struct scsi_cmnd *scsi_cmnd) debug_text_event(adapter->cmd_dbf, level, ""); debug_text_event(adapter->cmd_dbf, level, ""); } - write_unlock_irqrestore(&adapter->cmd_dbf_lock, flags); + spin_unlock_irqrestore(&adapter->dbf_lock, flags); } void @@ -278,7 +278,7 @@ zfcp_init_device_configure(void) goto out_unit; up(&zfcp_data.config_sema); ccw_device_set_online(adapter->ccw_device); - wait_event(unit->scsi_add_wq, atomic_read(&unit->scsi_add_work) == 0); + zfcp_erp_wait(adapter); down(&zfcp_data.config_sema); zfcp_unit_put(unit); out_unit: @@ -308,14 +308,13 @@ zfcp_module_init(void) if (!zfcp_transport_template) return -ENODEV; -#ifdef CONFIG_S390_SUPPORT retval = register_ioctl32_conversion(zfcp_ioctl_trans.cmd, zfcp_ioctl_trans.handler); if (retval != 0) { ZFCP_LOG_INFO("registration of ioctl32 conversion failed\n"); - goto out_ioctl32; + goto out; } -#endif + retval = misc_register(&zfcp_cfdc_misc); if (retval != 0) { ZFCP_LOG_INFO("registration of misc device " @@ -350,11 +349,7 @@ zfcp_module_init(void) out_ccw_register: misc_deregister(&zfcp_cfdc_misc); out_misc_register: -#ifdef CONFIG_S390_SUPPORT unregister_ioctl32_conversion(zfcp_ioctl_trans.cmd); - out_ioctl32: -#endif - out: return retval; } @@ -379,7 +374,7 @@ static int zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, unsigned int command, unsigned long buffer) { - struct zfcp_cfdc_sense_data sense_data, __user *sense_data_user; + struct zfcp_cfdc_sense_data *sense_data, __user *sense_data_user; struct zfcp_adapter *adapter = NULL; struct zfcp_fsf_req *fsf_req = NULL; struct zfcp_sg_list *sg_list = NULL; @@ -387,6 +382,12 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, char *bus_id = NULL; int retval = 0; + sense_data = kmalloc(sizeof(struct zfcp_cfdc_sense_data), GFP_KERNEL); + if (sense_data == NULL) { + retval = -ENOMEM; + goto out; + } + sg_list = kmalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL); if (sg_list == NULL) { retval = -ENOMEM; @@ -406,21 +407,21 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, goto out; } - retval = copy_from_user(&sense_data, sense_data_user, + retval = copy_from_user(sense_data, sense_data_user, sizeof(struct zfcp_cfdc_sense_data)); if (retval) { retval = -EFAULT; goto out; } - if (sense_data.signature != ZFCP_CFDC_SIGNATURE) { + if (sense_data->signature != ZFCP_CFDC_SIGNATURE) { ZFCP_LOG_INFO("invalid sense data request signature 0x%08x\n", ZFCP_CFDC_SIGNATURE); retval = -EINVAL; goto out; } - switch (sense_data.command) { + switch (sense_data->command) { case ZFCP_CFDC_CMND_DOWNLOAD_NORMAL: fsf_command = FSF_QTCB_DOWNLOAD_CONTROL_FILE; @@ -449,7 +450,7 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, default: ZFCP_LOG_INFO("invalid command code 0x%08x\n", - sense_data.command); + sense_data->command); retval = -EINVAL; goto out; } @@ -460,9 +461,9 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, goto out; } snprintf(bus_id, BUS_ID_SIZE, "%d.%d.%04x", - (sense_data.devno >> 24), - (sense_data.devno >> 16) & 0xFF, - (sense_data.devno & 0xFFFF)); + (sense_data->devno >> 24), + (sense_data->devno >> 16) & 0xFF, + (sense_data->devno & 0xFFFF)); read_lock_irq(&zfcp_data.config_lock); adapter = zfcp_get_adapter_by_busid(bus_id); @@ -478,7 +479,7 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, goto out; } - if (sense_data.command & ZFCP_CFDC_WITH_CONTROL_FILE) { + if (sense_data->command & ZFCP_CFDC_WITH_CONTROL_FILE) { retval = zfcp_sg_list_alloc(sg_list, ZFCP_CFDC_MAX_CONTROL_FILE_SIZE); if (retval) { @@ -487,8 +488,8 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, } } - if ((sense_data.command & ZFCP_CFDC_DOWNLOAD) && - (sense_data.command & ZFCP_CFDC_WITH_CONTROL_FILE)) { + if ((sense_data->command & ZFCP_CFDC_DOWNLOAD) && + (sense_data->command & ZFCP_CFDC_WITH_CONTROL_FILE)) { retval = zfcp_sg_list_copy_from_user( sg_list, &sense_data_user->control_file, ZFCP_CFDC_MAX_CONTROL_FILE_SIZE); @@ -498,19 +499,10 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, } } - retval = zfcp_fsf_control_file( - adapter, &fsf_req, fsf_command, option, sg_list); - if (retval == -EOPNOTSUPP) { - ZFCP_LOG_INFO("adapter does not support cfdc\n"); - goto out; - } else if (retval != 0) { - ZFCP_LOG_INFO("initiation of cfdc up/download failed\n"); - retval = -EPERM; + retval = zfcp_fsf_control_file(adapter, &fsf_req, fsf_command, + option, sg_list); + if (retval) goto out; - } - - wait_event(fsf_req->completion_wq, - fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); if ((fsf_req->qtcb->prefix.prot_status != FSF_PROT_GOOD) && (fsf_req->qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { @@ -518,20 +510,20 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, goto out; } - sense_data.fsf_status = fsf_req->qtcb->header.fsf_status; - memcpy(&sense_data.fsf_status_qual, + sense_data->fsf_status = fsf_req->qtcb->header.fsf_status; + memcpy(&sense_data->fsf_status_qual, &fsf_req->qtcb->header.fsf_status_qual, sizeof(union fsf_status_qual)); - memcpy(&sense_data.payloads, &fsf_req->qtcb->bottom.support.els, 256); + memcpy(&sense_data->payloads, &fsf_req->qtcb->bottom.support.els, 256); - retval = copy_to_user(sense_data_user, &sense_data, + retval = copy_to_user(sense_data_user, sense_data, sizeof(struct zfcp_cfdc_sense_data)); if (retval) { retval = -EFAULT; goto out; } - if (sense_data.command & ZFCP_CFDC_UPLOAD) { + if (sense_data->command & ZFCP_CFDC_UPLOAD) { retval = zfcp_sg_list_copy_to_user( &sense_data_user->control_file, sg_list, ZFCP_CFDC_MAX_CONTROL_FILE_SIZE); @@ -553,6 +545,9 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, kfree(sg_list); } + if (sense_data != NULL) + kfree(sense_data); + return retval; } @@ -588,18 +583,19 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size) retval = -ENOMEM; goto out; } + memset(sg_list->sg, sg_list->count * sizeof(struct scatterlist), 0); for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) { sg->length = min(size, PAGE_SIZE); sg->offset = 0; address = (void *) get_zeroed_page(GFP_KERNEL); - zfcp_address_to_sg(address, sg); - if (sg->page == NULL) { + if (address == NULL) { sg_list->count = i; zfcp_sg_list_free(sg_list); retval = -ENOMEM; goto out; } + zfcp_address_to_sg(address, sg); size -= sg->length; } @@ -624,7 +620,7 @@ zfcp_sg_list_free(struct zfcp_sg_list *sg_list) BUG_ON(sg_list == NULL); for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) - __free_pages(sg->page, 0); + free_page((unsigned long) zfcp_sg_to_address(sg)); sg_list->count = 0; kfree(sg_list->sg); @@ -865,7 +861,6 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) return NULL; memset(unit, 0, sizeof (struct zfcp_unit)); - init_waitqueue_head(&unit->scsi_add_wq); /* initialise reference count stuff */ atomic_set(&unit->refcount, 0); init_waitqueue_head(&unit->remove_wq); @@ -1039,11 +1034,11 @@ zfcp_adapter_debug_register(struct zfcp_adapter *adapter) char dbf_name[20]; /* debug feature area which records SCSI command failures (hostbyte) */ - rwlock_init(&adapter->cmd_dbf_lock); + spin_lock_init(&adapter->dbf_lock); + sprintf(dbf_name, ZFCP_CMD_DBF_NAME "%s", zfcp_get_busid_by_adapter(adapter)); - adapter->cmd_dbf = debug_register(dbf_name, - ZFCP_CMD_DBF_INDEX, + adapter->cmd_dbf = debug_register(dbf_name, ZFCP_CMD_DBF_INDEX, ZFCP_CMD_DBF_AREAS, ZFCP_CMD_DBF_LENGTH); debug_register_view(adapter->cmd_dbf, &debug_hex_ascii_view); @@ -1052,40 +1047,38 @@ zfcp_adapter_debug_register(struct zfcp_adapter *adapter) /* debug feature area which records SCSI command aborts */ sprintf(dbf_name, ZFCP_ABORT_DBF_NAME "%s", zfcp_get_busid_by_adapter(adapter)); - adapter->abort_dbf = debug_register(dbf_name, - ZFCP_ABORT_DBF_INDEX, + adapter->abort_dbf = debug_register(dbf_name, ZFCP_ABORT_DBF_INDEX, ZFCP_ABORT_DBF_AREAS, ZFCP_ABORT_DBF_LENGTH); debug_register_view(adapter->abort_dbf, &debug_hex_ascii_view); debug_set_level(adapter->abort_dbf, ZFCP_ABORT_DBF_LEVEL); - /* debug feature area which records SCSI command aborts */ + /* debug feature area which records incoming ELS commands */ sprintf(dbf_name, ZFCP_IN_ELS_DBF_NAME "%s", zfcp_get_busid_by_adapter(adapter)); - adapter->in_els_dbf = debug_register(dbf_name, - ZFCP_IN_ELS_DBF_INDEX, + adapter->in_els_dbf = debug_register(dbf_name, ZFCP_IN_ELS_DBF_INDEX, ZFCP_IN_ELS_DBF_AREAS, ZFCP_IN_ELS_DBF_LENGTH); debug_register_view(adapter->in_els_dbf, &debug_hex_ascii_view); debug_set_level(adapter->in_els_dbf, ZFCP_IN_ELS_DBF_LEVEL); - /* debug feature area which records erp events */ sprintf(dbf_name, ZFCP_ERP_DBF_NAME "%s", zfcp_get_busid_by_adapter(adapter)); - adapter->erp_dbf = debug_register(dbf_name, - ZFCP_ERP_DBF_INDEX, + adapter->erp_dbf = debug_register(dbf_name, ZFCP_ERP_DBF_INDEX, ZFCP_ERP_DBF_AREAS, ZFCP_ERP_DBF_LENGTH); debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view); debug_set_level(adapter->erp_dbf, ZFCP_ERP_DBF_LEVEL); - if (adapter->cmd_dbf && adapter->abort_dbf && - adapter->in_els_dbf && adapter->erp_dbf) - return 0; + if (!(adapter->cmd_dbf && adapter->abort_dbf && + adapter->in_els_dbf && adapter->erp_dbf)) { + zfcp_adapter_debug_unregister(adapter); + return -ENOMEM; + } + + return 0; - zfcp_adapter_debug_unregister(adapter); - return -ENOMEM; } /** @@ -1095,10 +1088,14 @@ zfcp_adapter_debug_register(struct zfcp_adapter *adapter) void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter) { - debug_unregister(adapter->erp_dbf); - debug_unregister(adapter->cmd_dbf); - debug_unregister(adapter->abort_dbf); - debug_unregister(adapter->in_els_dbf); + debug_unregister(adapter->abort_dbf); + debug_unregister(adapter->cmd_dbf); + debug_unregister(adapter->erp_dbf); + debug_unregister(adapter->in_els_dbf); + adapter->abort_dbf = NULL; + adapter->cmd_dbf = NULL; + adapter->erp_dbf = NULL; + adapter->in_els_dbf = NULL; } void @@ -1651,7 +1648,6 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req) zfcp_fsf_incoming_els_rscn(adapter, status_buffer); else zfcp_fsf_incoming_els_unknown(adapter, status_buffer); - }