diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 12:30:30 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-04 12:30:30 -0700 |
commit | 84cbd7222b2b00dcddef3103203986b3d59c836a (patch) | |
tree | cdbe55ec410f853d4d532ed3252334cb110d5985 /drivers/s390 | |
parent | 80cc38b16389849a6e06441ace4530f6b2497c3c (diff) | |
parent | a3fda7dd5179989dd0ead820dcebd13f956ddec1 (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley:
"The patch set is mostly driver updates (usf, zfcp, lpfc, mpt2sas,
megaraid_sas, bfa, ipr) and a few bug fixes. Also of note is that the
Buslogic driver has been rewritten to a better coding style and 64 bit
support added. We also removed the libsas limitation on 16 bytes for
the command size (currently no drivers make use of this)"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (101 commits)
[SCSI] megaraid: minor cut and paste error fixed.
[SCSI] ufshcd-pltfrm: remove unnecessary dma_set_coherent_mask() call
[SCSI] ufs: fix register address in UIC error interrupt handling
[SCSI] ufshcd-pltfrm: add missing empty slot in ufs_of_match[]
[SCSI] ufs: use devres functions for ufshcd
[SCSI] ufs: Fix the response UPIU length setting
[SCSI] ufs: rework link start-up process
[SCSI] ufs: remove version check before IS reg clear
[SCSI] ufs: amend interrupt configuration
[SCSI] ufs: wrap the i/o access operations
[SCSI] storvsc: Update the storage protocol to win8 level
[SCSI] storvsc: Increase the value of scsi timeout for storvsc devices
[SCSI] MAINTAINERS: Add myself as the maintainer for BusLogic SCSI driver
[SCSI] BusLogic: Port driver to 64-bit.
[SCSI] BusLogic: Fix style issues
[SCSI] libiscsi: Added new boot entries in the session sysfs
[SCSI] aacraid: Fix for arrays are going offline in the system. System hangs
[SCSI] ipr: IOA Status Code(IOASC) update
[SCSI] sd: Update WRITE SAME heuristics
[SCSI] fnic: potential dead lock in fnic_is_abts_pending()
...
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/Makefile | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 36 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 13 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_cfdc.c | 446 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 11 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 4 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 3 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 20 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 154 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.h | 26 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 10 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 27 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_unit.c | 9 |
14 files changed, 74 insertions, 689 deletions
diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index c454ffebb63e..9259039e886d 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile @@ -2,7 +2,7 @@ # Makefile for the S/390 specific device drivers # -zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_cfdc.o zfcp_dbf.o zfcp_erp.o \ +zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_dbf.o zfcp_erp.o \ zfcp_fc.o zfcp_fsf.o zfcp_qdio.o zfcp_scsi.o zfcp_sysfs.o \ zfcp_unit.o diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index f6adde44f226..1b9e4aee914b 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -3,7 +3,7 @@ * * Module interface and handling of zfcp data structures. * - * Copyright IBM Corp. 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ /* @@ -23,6 +23,7 @@ * Christof Schmitt * Martin Petermann * Sven Schuetz + * Steffen Maier */ #define KMSG_COMPONENT "zfcp" @@ -140,13 +141,6 @@ static int __init zfcp_module_init(void) scsi_transport_reserve_device(zfcp_scsi_transport_template, sizeof(struct zfcp_scsi_dev)); - - retval = misc_register(&zfcp_cfdc_misc); - if (retval) { - pr_err("Registering the misc device zfcp_cfdc failed\n"); - goto out_misc; - } - retval = ccw_driver_register(&zfcp_ccw_driver); if (retval) { pr_err("The zfcp device driver could not register with " @@ -159,8 +153,6 @@ static int __init zfcp_module_init(void) return 0; out_ccw_register: - misc_deregister(&zfcp_cfdc_misc); -out_misc: fc_release_transport(zfcp_scsi_transport_template); out_transport: kmem_cache_destroy(zfcp_fc_req_cache); @@ -175,7 +167,6 @@ module_init(zfcp_module_init); static void __exit zfcp_module_exit(void) { ccw_driver_unregister(&zfcp_ccw_driver); - misc_deregister(&zfcp_cfdc_misc); fc_release_transport(zfcp_scsi_transport_template); kmem_cache_destroy(zfcp_fc_req_cache); kmem_cache_destroy(zfcp_fsf_qtcb_cache); @@ -415,6 +406,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; + adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; + if (!zfcp_scsi_adapter_register(adapter)) return adapter; @@ -464,20 +457,6 @@ void zfcp_adapter_release(struct kref *ref) put_device(&cdev->dev); } -/** - * zfcp_device_unregister - remove port, unit from system - * @dev: reference to device which is to be removed - * @grp: related reference to attribute group - * - * Helper function to unregister port, unit from system - */ -void zfcp_device_unregister(struct device *dev, - const struct attribute_group *grp) -{ - sysfs_remove_group(&dev->kobj, grp); - device_unregister(dev); -} - static void zfcp_port_release(struct device *dev) { struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); @@ -530,6 +509,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, port->wwpn = wwpn; port->rport_task = RPORT_NONE; port->dev.parent = &adapter->ccw_device->dev; + port->dev.groups = zfcp_port_attr_groups; port->dev.release = zfcp_port_release; if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { @@ -543,10 +523,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, goto err_out; } - if (sysfs_create_group(&port->dev.kobj, - &zfcp_sysfs_port_attrs)) - goto err_out_put; - write_lock_irq(&adapter->port_list_lock); list_add_tail(&port->list, &adapter->port_list); write_unlock_irq(&adapter->port_list_lock); @@ -555,8 +531,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, return port; -err_out_put: - device_unregister(&port->dev); err_out: zfcp_ccw_adapter_put(adapter); return ERR_PTR(retval); diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index f2dd3a0a39eb..f9879d400d0e 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -72,15 +72,6 @@ static struct ccw_device_id zfcp_ccw_device_id[] = { MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); /** - * zfcp_ccw_priv_sch - check if subchannel is privileged - * @adapter: Adapter/Subchannel to check - */ -int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter) -{ - return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV; -} - -/** * zfcp_ccw_probe - probe function of zfcp driver * @cdev: pointer to belonging ccw device * @@ -129,10 +120,10 @@ static void zfcp_ccw_remove(struct ccw_device *cdev) zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */ list_for_each_entry_safe(unit, u, &unit_remove_lh, list) - zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); + device_unregister(&unit->dev); list_for_each_entry_safe(port, p, &port_remove_lh, list) - zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); + device_unregister(&port->dev); zfcp_adapter_unregister(adapter); } diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c deleted file mode 100644 index 49b82e46629e..000000000000 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * zfcp device driver - * - * Userspace interface for accessing the - * Access Control Lists / Control File Data Channel; - * handling of response code and states for ports and LUNs. - * - * Copyright IBM Corp. 2008, 2010 - */ - -#define KMSG_COMPONENT "zfcp" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt - -#include <linux/compat.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/miscdevice.h> -#include <asm/compat.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) -{ - char busid[9]; - struct ccw_device *cdev; - struct zfcp_adapter *adapter; - - snprintf(busid, sizeof(busid), "0.0.%04x", devno); - cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); - if (!cdev) - return NULL; - - adapter = zfcp_ccw_adapter_by_cdev(cdev); - - put_device(&cdev->dev); - 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 arg) -{ - 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; - - if (is_compat_task()) - data_user = compat_ptr(arg); - else - data_user = (void __user *)arg; - - if (!data_user) - return -EINVAL; - - fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL); - if (!fsf_cfdc) - return -ENOMEM; - - data = memdup_user(data_user, sizeof(*data_user)); - if (IS_ERR(data)) { - retval = PTR_ERR(data); - goto no_mem_sense; - } - - 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_ccw_adapter_put(adapter); - free_buffer: - kfree(data); - no_mem_sense: - kfree(fsf_cfdc); - return retval; -} - -static const struct file_operations zfcp_cfdc_fops = { - .open = nonseekable_open, - .unlocked_ioctl = zfcp_cfdc_dev_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = zfcp_cfdc_dev_ioctl, -#endif - .llseek = no_llseek, -}; - -struct miscdevice zfcp_cfdc_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "zfcp_cfdc", - .fops = &zfcp_cfdc_fops, -}; - -/** - * zfcp_cfdc_adapter_access_changed - Process change in adapter ACT - * @adapter: Adapter where the Access Control Table (ACT) changed - * - * After a change in the adapter ACT, check if access to any - * previously denied resources is now possible. - */ -void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter) -{ - unsigned long flags; - struct zfcp_port *port; - struct scsi_device *sdev; - struct zfcp_scsi_dev *zfcp_sdev; - int status; - - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) - return; - - read_lock_irqsave(&adapter->port_list_lock, flags); - list_for_each_entry(port, &adapter->port_list, list) { - status = atomic_read(&port->status); - if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) || - (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) - zfcp_erp_port_reopen(port, - ZFCP_STATUS_COMMON_ERP_FAILED, - "cfaac_1"); - } - read_unlock_irqrestore(&adapter->port_list_lock, flags); - - shost_for_each_device(sdev, adapter->scsi_host) { - zfcp_sdev = sdev_to_zfcp(sdev); - status = atomic_read(&zfcp_sdev->status); - if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) || - (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) - zfcp_erp_lun_reopen(sdev, - ZFCP_STATUS_COMMON_ERP_FAILED, - "cfaac_2"); - } -} - -static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) -{ - u16 subtable = table >> 16; - u16 rule = table & 0xffff; - const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" }; - - if (subtable && subtable < ARRAY_SIZE(act_type)) - dev_warn(&adapter->ccw_device->dev, - "Access denied according to ACT rule type %s, " - "rule %d\n", act_type[subtable], rule); -} - -/** - * zfcp_cfdc_port_denied - Process "access denied" for port - * @port: The port where the access has been denied - * @qual: The FSF status qualifier for the access denied FSF status - */ -void zfcp_cfdc_port_denied(struct zfcp_port *port, - union fsf_status_qual *qual) -{ - dev_warn(&port->adapter->ccw_device->dev, - "Access denied to port 0x%016Lx\n", - (unsigned long long)port->wwpn); - - zfcp_act_eval_err(port->adapter, qual->halfword[0]); - zfcp_act_eval_err(port->adapter, qual->halfword[1]); - zfcp_erp_set_port_status(port, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED); -} - -/** - * zfcp_cfdc_lun_denied - Process "access denied" for LUN - * @sdev: The SCSI device / LUN where the access has been denied - * @qual: The FSF status qualifier for the access denied FSF status - */ -void zfcp_cfdc_lun_denied(struct scsi_device *sdev, - union fsf_status_qual *qual) -{ - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - - dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, - "Access denied to LUN 0x%016Lx on port 0x%016Lx\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]); - zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]); - zfcp_erp_set_lun_status(sdev, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED); - - atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); -} - -/** - * zfcp_cfdc_lun_shrng_vltn - Evaluate LUN sharing violation status - * @sdev: The LUN / SCSI device where sharing violation occurred - * @qual: The FSF status qualifier from the LUN sharing violation - */ -void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev, - union fsf_status_qual *qual) -{ - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - - if (qual->word[0]) - dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, - "LUN 0x%Lx on port 0x%Lx is already in " - "use by CSS%d, MIF Image ID %x\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn, - qual->fsf_queue_designator.cssid, - qual->fsf_queue_designator.hla); - else - zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]); - - zfcp_erp_set_lun_status(sdev, - ZFCP_STATUS_COMMON_ERP_FAILED | - ZFCP_STATUS_COMMON_ACCESS_DENIED); - atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); -} - -/** - * zfcp_cfdc_open_lun_eval - Eval access ctrl. status for successful "open lun" - * @sdev: The SCSI device / LUN where to evaluate the status - * @bottom: The qtcb bottom with the status from the "open lun" - * - * Returns: 0 if LUN is usable, -EACCES if the access control table - * reports an unsupported configuration. - */ -int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev, - struct fsf_qtcb_bottom_support *bottom) -{ - int shared, rw; - struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; - - if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) || - !(adapter->adapter_features & FSF_FEATURE_LUN_SHARING) || - zfcp_ccw_priv_sch(adapter)) - return 0; - - shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE); - rw = (bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER); - - if (shared) - atomic_set_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status); - - if (!rw) { - atomic_set_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status); - dev_info(&adapter->ccw_device->dev, "SCSI device at LUN " - "0x%016Lx on port 0x%016Lx opened read-only\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - } - - if (!shared && !rw) { - dev_err(&adapter->ccw_device->dev, "Exclusive read-only access " - "not supported (LUN 0x%016Lx, port 0x%016Lx)\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); - zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6"); - return -EACCES; - } - - if (shared && rw) { - dev_err(&adapter->ccw_device->dev, - "Shared read-write access not supported " - "(LUN 0x%016Lx, port 0x%016Lx)\n", - zfcp_scsi_dev_lun(sdev), - (unsigned long long)zfcp_sdev->port->wwpn); - zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); - zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8"); - return -EACCES; - } - - return 0; -} diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index e1a8cc2526e7..132a905b6bdb 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -3,7 +3,7 @@ * * Debug traces for zfcp. * - * Copyright IBM Corp. 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ #define KMSG_COMPONENT "zfcp" @@ -23,6 +23,13 @@ module_param(dbfsize, uint, 0400); MODULE_PARM_DESC(dbfsize, "number of pages for each debug feature area (default 4)"); +static u32 dbflevel = 3; + +module_param(dbflevel, uint, 0400); +MODULE_PARM_DESC(dbflevel, + "log level for each debug feature area " + "(default 3, range 0..6)"); + static inline unsigned int zfcp_dbf_plen(unsigned int offset) { return sizeof(struct zfcp_dbf_pay) + offset - ZFCP_DBF_PAY_MAX_REC; @@ -447,7 +454,7 @@ static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size) return NULL; debug_register_view(d, &debug_hex_ascii_view); - debug_set_level(d, 3); + debug_set_level(d, dbflevel); return d; } diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 1305955cbf59..d91173f326c5 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -86,10 +86,6 @@ struct zfcp_reqlist; #define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 #define ZFCP_STATUS_PORT_LINK_TEST 0x00000002 -/* logical unit status */ -#define ZFCP_STATUS_LUN_SHARED 0x00000004 -#define ZFCP_STATUS_LUN_READONLY 0x00000008 - /* FSF request status (this does not have a common part) */ #define ZFCP_STATUS_FSFREQ_ERROR 0x00000008 #define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010 diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 4133ab6e20f1..1d4c8fe72752 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -950,8 +950,7 @@ static void zfcp_erp_lun_strategy_clearstati(struct scsi_device *sdev) { struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); - atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_LUN_SHARED | ZFCP_STATUS_LUN_READONLY, + atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &zfcp_sdev->status); } diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 1d3dd3f7d699..83e3f1408c38 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -21,28 +21,14 @@ extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32, u32); extern void zfcp_sg_free_table(struct scatterlist *, int); extern int zfcp_sg_setup_table(struct scatterlist *, int); -extern void zfcp_device_unregister(struct device *, - const struct attribute_group *); extern void zfcp_adapter_release(struct kref *); extern void zfcp_adapter_unregister(struct zfcp_adapter *); /* zfcp_ccw.c */ -extern int zfcp_ccw_priv_sch(struct zfcp_adapter *); extern struct ccw_driver zfcp_ccw_driver; extern struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *); extern void zfcp_ccw_adapter_put(struct zfcp_adapter *); -/* zfcp_cfdc.c */ -extern struct miscdevice zfcp_cfdc_misc; -extern void zfcp_cfdc_port_denied(struct zfcp_port *, union fsf_status_qual *); -extern void zfcp_cfdc_lun_denied(struct scsi_device *, union fsf_status_qual *); -extern void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *, - union fsf_status_qual *); -extern int zfcp_cfdc_open_lun_eval(struct scsi_device *, - struct fsf_qtcb_bottom_support *); -extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *); - - /* zfcp_dbf.c */ extern int zfcp_dbf_adapter_register(struct zfcp_adapter *); extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *); @@ -117,8 +103,6 @@ extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *, extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *, struct fsf_qtcb_bottom_port *); -extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *, - struct zfcp_fsf_cfdc *); extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); extern int zfcp_fsf_status_read(struct zfcp_qdio *); extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); @@ -158,9 +142,9 @@ extern void zfcp_scsi_set_prot(struct zfcp_adapter *); extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int); /* zfcp_sysfs.c */ -extern struct attribute_group zfcp_sysfs_unit_attrs; +extern const struct attribute_group *zfcp_unit_attr_groups[]; extern struct attribute_group zfcp_sysfs_adapter_attrs; -extern struct attribute_group zfcp_sysfs_port_attrs; +extern const struct attribute_group *zfcp_port_attr_groups[]; extern struct mutex zfcp_sysfs_port_units_mutex; extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; extern struct device_attribute *zfcp_sysfs_shost_attrs[]; diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index ff598cd68b2d..ca28e1c66115 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -668,7 +668,7 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_req *fc_req, list_for_each_entry_safe(port, tmp, &remove_lh, list) { zfcp_erp_port_shutdown(port, 0, "fcegpf2"); - zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); + device_unregister(&port->dev); } return ret; diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index c7e148f33b2a..510e9b06c1a1 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3,7 +3,7 @@ * * Implementation of FSF commands. * - * Copyright IBM Corp. 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ #define KMSG_COMPONENT "zfcp" @@ -254,14 +254,9 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) break; case FSF_STATUS_READ_NOTIFICATION_LOST: - if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) - zfcp_cfdc_adapter_access_changed(adapter); if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS) zfcp_fc_conditional_port_scan(adapter); break; - case FSF_STATUS_READ_CFDC_UPDATED: - zfcp_cfdc_adapter_access_changed(adapter); - break; case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: adapter->adapter_features = sr_buf->payload.word[0]; break; @@ -483,12 +478,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) fc_host_port_name(shost) = nsp->fl_wwpn; fc_host_node_name(shost) = nsp->fl_wwnn; - fc_host_port_id(shost) = ntoh24(bottom->s_id); - fc_host_speed(shost) = - zfcp_fsf_convert_portspeed(bottom->fc_link_speed); fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; - adapter->hydra_version = bottom->adapter_type; adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; adapter->stat_read_buf_num = max(bottom->status_read_buf_num, (u16)FSF_STATUS_READS_RECOM); @@ -496,6 +487,19 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) if (fc_host_permanent_port_name(shost) == -1) fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + zfcp_scsi_set_prot(adapter); + + /* no error return above here, otherwise must fix call chains */ + /* do not evaluate invalid fields */ + if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE) + return 0; + + fc_host_port_id(shost) = ntoh24(bottom->s_id); + fc_host_speed(shost) = + zfcp_fsf_convert_portspeed(bottom->fc_link_speed); + + adapter->hydra_version = bottom->adapter_type; + switch (bottom->fc_topology) { case FSF_TOPO_P2P: adapter->peer_d_id = ntoh24(bottom->peer_d_id); @@ -517,8 +521,6 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) return -EIO; } - zfcp_scsi_set_prot(adapter); - return 0; } @@ -563,8 +565,14 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; adapter->hydra_version = 0; + /* avoids adapter shutdown to be able to recognize + * events such as LINK UP */ + atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, + &adapter->status); zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); + if (zfcp_fsf_exchange_config_evaluate(req)) + return; break; default: zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3"); @@ -931,8 +939,6 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) break; } break; - case FSF_ACCESS_DENIED: - break; case FSF_PORT_BOXED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -1086,7 +1092,6 @@ out: static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) { struct zfcp_fsf_ct_els *send_els = req->data; - struct zfcp_port *port = send_els->port; struct fsf_qtcb_header *header = &req->qtcb->header; send_els->status = -EINVAL; @@ -1116,12 +1121,6 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) case FSF_REQUEST_SIZE_TOO_LARGE: case FSF_RESPONSE_SIZE_TOO_LARGE: break; - case FSF_ACCESS_DENIED: - if (port) { - zfcp_cfdc_port_denied(port, &header->fsf_status_qual); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - } - break; case FSF_SBAL_MISMATCH: /* should never occur, avoided in zfcp_fsf_send_els */ /* fall through */ @@ -1209,8 +1208,6 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); req->qtcb->bottom.config.feature_selection = - FSF_FEATURE_CFDC | - FSF_FEATURE_LUN_SHARING | FSF_FEATURE_NOTIFICATION_LOST | FSF_FEATURE_UPDATE_ALERT; req->erp_action = erp_action; @@ -1250,8 +1247,6 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, req->handler = zfcp_fsf_exchange_config_data_handler; req->qtcb->bottom.config.feature_selection = - FSF_FEATURE_CFDC | - FSF_FEATURE_LUN_SHARING | FSF_FEATURE_NOTIFICATION_LOST | FSF_FEATURE_UPDATE_ALERT; @@ -1378,10 +1373,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) switch (header->fsf_status) { case FSF_PORT_ALREADY_OPEN: break; - case FSF_ACCESS_DENIED: - zfcp_cfdc_port_denied(port, &header->fsf_status_qual); - req->status |= ZFCP_STATUS_FSFREQ_ERROR; - break; case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: dev_warn(&req->adapter->ccw_device->dev, "Not enough FCP adapter resources to open " @@ -1564,8 +1555,6 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) /* fall through */ case FSF_ADAPTER_STATUS_AVAILABLE: req->status |= ZFCP_STATUS_FSFREQ_ERROR; - /* fall through */ - case FSF_ACCESS_DENIED: wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; break; case FSF_GOOD: @@ -1685,9 +1674,6 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1"); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; - case FSF_ACCESS_DENIED: - zfcp_cfdc_port_denied(port, &header->fsf_status_qual); - break; case FSF_PORT_BOXED: /* can't use generic zfcp_erp_modify_port_status because * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ @@ -1773,7 +1759,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req) struct scsi_device *sdev = req->data; struct zfcp_scsi_dev *zfcp_sdev; struct fsf_qtcb_header *header = &req->qtcb->header; - struct fsf_qtcb_bottom_su |