Commit bd307f59 authored by Andreas Herrmann's avatar Andreas Herrmann Committed by Linus Torvalds

[PATCH] s390: zfcp host adapter

zfcp host adapter change:
 - Return -EIO if wait_event_interruptible_timeout was interrupted.
 - Reduce stack uage of zfcp_cfdc_dev_ioctl.
 - Make zfcp_sg_list_[alloc,free] more consistent.
 - Store driver version to zfcp_data structure.
 - Add missing FSF states and make corresponding log messages consistent.
 - Always wait for completion in zfcp_scsi_command_sync.
 - Add Andreas to authors list.
 - Add timeout for cfdc upload/download.
 - Add support for temporary units (units not registered to the scsi stack).
 - Allow sending of ELS commands to ports by their d_id.
 - Increase port refcount while link test is running.
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4d2d2d6b
......@@ -12,6 +12,7 @@
* Wolfgang Taphorn
* Stefan Bader <stefan.bader@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -29,7 +30,7 @@
*/
/* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_AUX_REVISION "$Revision: 1.129 $"
#define ZFCP_AUX_REVISION "$Revision: 1.135 $"
#include "zfcp_ext.h"
......@@ -80,6 +81,7 @@ static struct miscdevice zfcp_cfdc_misc = {
module_init(zfcp_module_init);
MODULE_AUTHOR("Heiko Carstens <heiko.carstens@de.ibm.com>, "
"Andreas Herrman <aherrman@de.ibm.com>, "
"Martin Peschke <mpeschke@de.ibm.com>, "
"Raimund Schroeder <raimund.schroeder@de.ibm.com>, "
"Wolfgang Taphorn <taphorn@de.ibm.com>, "
......@@ -379,7 +381,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 +389,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 +414,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 +457,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 +468,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 +486,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 +495,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 +506,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 +517,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 +552,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 +590,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 +627,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);
......
......@@ -10,6 +10,7 @@
* Authors:
* Martin Peschke <mpeschke@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -26,7 +27,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_CCW_C_REVISION "$Revision: 1.56 $"
#define ZFCP_CCW_C_REVISION "$Revision: 1.57 $"
#include "zfcp_ext.h"
......
......@@ -12,6 +12,7 @@
* Wolfgang Taphorn
* Stefan Bader <stefan.bader@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -33,7 +34,7 @@
#define ZFCP_DEF_H
/* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_DEF_REVISION "$Revision: 1.91 $"
#define ZFCP_DEF_REVISION "$Revision: 1.98 $"
/*************************** INCLUDES *****************************************/
......@@ -71,7 +72,7 @@
/********************* GENERAL DEFINES *********************************/
/* zfcp version number, it consists of major, minor, and patch-level number */
#define ZFCP_VERSION "4.1.3"
#define ZFCP_VERSION "4.1.4"
/**
* zfcp_sg_to_address - determine kernel address from struct scatterlist
......@@ -598,6 +599,7 @@ do { \
/* logical unit status */
#define ZFCP_STATUS_UNIT_NOTSUPPUNITRESET 0x00000001
#define ZFCP_STATUS_UNIT_TEMPORARY 0x00000010
/* FSF request status (this does not have a common part) */
......@@ -817,7 +819,8 @@ typedef void (*zfcp_send_els_handler_t)(unsigned long);
/**
* struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
* @port: port where the request is sent to
* @adapter: adapter where request is sent from
* @d_id: destiniation id of port where request is sent to
* @req: scatter-gather list for request
* @resp: scatter-gather list for response
* @req_count: number of elements in request scatter-gather list
......@@ -830,7 +833,8 @@ typedef void (*zfcp_send_els_handler_t)(unsigned long);
* @status: used to pass error status to calling function
*/
struct zfcp_send_els {
struct zfcp_port *port;
struct zfcp_adapter *adapter;
fc_id_t d_id;
struct scatterlist *req;
struct scatterlist *resp;
unsigned int req_count;
......@@ -1055,6 +1059,7 @@ struct zfcp_data {
char init_busid[BUS_ID_SIZE];
wwn_t init_wwpn;
fcp_lun_t init_fcp_lun;
char *driver_version;
};
/**
......
......@@ -12,6 +12,7 @@
* Wolfgang Taphorn
* Stefan Bader <stefan.bader@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -31,7 +32,7 @@
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP
/* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_ERP_REVISION "$Revision: 1.65 $"
#define ZFCP_ERP_REVISION "$Revision: 1.69 $"
#include "zfcp_ext.h"
......@@ -336,7 +337,8 @@ zfcp_els(struct zfcp_port *port, u8 ls_code)
send_els->req->offset = 0;
send_els->resp->offset = PAGE_SIZE >> 1;
send_els->port = port;
send_els->adapter = port->adapter;
send_els->d_id = port->d_id;
send_els->ls_code = ls_code;
send_els->handler = zfcp_els_handler;
send_els->handler_data = (unsigned long)send_els;
......@@ -441,7 +443,7 @@ void
zfcp_els_handler(unsigned long data)
{
struct zfcp_send_els *send_els = (struct zfcp_send_els*)data;
struct zfcp_port *port = send_els->port;
struct zfcp_port *port;
struct zfcp_ls_rtv_acc *rtv;
struct zfcp_ls_rls_acc *rls;
struct zfcp_ls_pdisc_acc *pdisc;
......@@ -449,6 +451,12 @@ zfcp_els_handler(unsigned long data)
void *req, *resp;
u8 req_code;
read_lock(&zfcp_data.config_lock);
port = zfcp_get_port_by_did(send_els->adapter, send_els->d_id);
read_unlock(&zfcp_data.config_lock);
BUG_ON(port == NULL);
/* request rejected or timed out */
if (send_els->status != 0) {
ZFCP_LOG_NORMAL("ELS request timed out, force physical port "
......@@ -521,6 +529,7 @@ zfcp_els_handler(unsigned long data)
}
out:
zfcp_port_put(port);
__free_pages(send_els->req->page, 0);
kfree(send_els->req);
kfree(send_els->resp);
......@@ -541,8 +550,10 @@ zfcp_test_link(struct zfcp_port *port)
{
int retval;
zfcp_port_get(port);
retval = zfcp_els(port, ZFCP_LS_ADISC);
if (retval != 0) {
zfcp_port_put(port);
ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "
"on adapter %s\n ", port->wwpn,
zfcp_get_busid_by_port(port));
......@@ -3445,21 +3456,20 @@ zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
/**
* zfcp_erp_action_cleanup
*
* registers unit with scsi stack if appropiate and fixes reference counts
* Register unit with scsi stack if appropiate and fix reference counts.
* Note: Temporary units are not registered with scsi stack.
*/
static void
zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
struct zfcp_port *port, struct zfcp_unit *unit,
int result)
{
if ((action == ZFCP_ERP_ACTION_REOPEN_UNIT)
&& (result == ZFCP_ERP_SUCCEEDED)
&& (!unit->device)) {
zfcp_erp_schedule_work(unit);
}
switch (action) {
case ZFCP_ERP_ACTION_REOPEN_UNIT:
if ((result == ZFCP_ERP_SUCCEEDED)
&& (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, &unit->status))
&& (!unit->device))
zfcp_erp_schedule_work(unit);
zfcp_unit_put(unit);
break;
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
......
......@@ -12,6 +12,7 @@
* Wolfgang Taphorn
* Stefan Bader <stefan.bader@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -31,7 +32,7 @@
#ifndef ZFCP_EXT_H
#define ZFCP_EXT_H
/* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_EXT_REVISION "$Revision: 1.57 $"
#define ZFCP_EXT_REVISION "$Revision: 1.58 $"
#include "zfcp_def.h"
......
This diff is collapsed.
......@@ -12,6 +12,7 @@
* Wolfgang Taphorn
* Stefan Bader <stefan.bader@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -105,6 +106,8 @@
#define FSF_PAYLOAD_SIZE_MISMATCH 0x00000060
#define FSF_REQUEST_SIZE_TOO_LARGE 0x00000061
#define FSF_RESPONSE_SIZE_TOO_LARGE 0x00000062
#define FSF_SBAL_MISMATCH 0x00000063
#define FSF_OPEN_PORT_WITHOUT_PRLI 0x00000064
#define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD
#define FSF_FCP_RSP_AVAILABLE 0x000000AF
#define FSF_UNKNOWN_COMMAND 0x000000E2
......
......@@ -12,6 +12,7 @@
* Raimund Schroeder <raimund.schroeder@de.ibm.com>
* Wolfgang Taphorn
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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,7 +29,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_QDIO_C_REVISION "$Revision: 1.19 $"
#define ZFCP_QDIO_C_REVISION "$Revision: 1.20 $"
#include "zfcp_ext.h"
......
......@@ -12,6 +12,7 @@
* Wolfgang Taphorn
* Stefan Bader <stefan.bader@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -31,7 +32,7 @@
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI
/* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_SCSI_REVISION "$Revision: 1.68 $"
#define ZFCP_SCSI_REVISION "$Revision: 1.71 $"
#include "zfcp_ext.h"
......@@ -81,7 +82,8 @@ struct zfcp_data zfcp_data = {
unchecked_isa_dma: 0,
use_clustering: 1,
sdev_attrs: zfcp_sysfs_sdev_attrs,
}
},
.driver_version = ZFCP_VERSION,
/* rest initialised with zeros */
};
......@@ -333,7 +335,7 @@ zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt,
scpnt->SCp.ptr = (void *) &wait; /* silent re-use */
scpnt->scsi_done = zfcp_scsi_command_sync_handler;
ret = zfcp_scsi_command_async(unit->port->adapter, unit, scpnt, timer);
if ((ret == 0) && (scpnt->result == 0))
if (ret == 0)
wait_for_completion(&wait);
scpnt->SCp.ptr = NULL;
......
......@@ -10,6 +10,7 @@
* Authors:
* Martin Peschke <mpeschke@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -26,7 +27,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_SYSFS_ADAPTER_C_REVISION "$Revision: 1.37 $"
#define ZFCP_SYSFS_ADAPTER_C_REVISION "$Revision: 1.38 $"
#include "zfcp_ext.h"
......
......@@ -10,6 +10,7 @@
* Authors:
* Martin Peschke <mpeschke@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -26,7 +27,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_SYSFS_DRIVER_C_REVISION "$Revision: 1.15 $"
#define ZFCP_SYSFS_DRIVER_C_REVISION "$Revision: 1.17 $"
#include "zfcp_ext.h"
......@@ -85,7 +86,7 @@ ZFCP_DEFINE_DRIVER_ATTR(fc, FC);
static ssize_t zfcp_sysfs_version_show(struct device_driver *dev,
char *buf)
{
return sprintf(buf, "%s\n", ZFCP_VERSION);
return sprintf(buf, "%s\n", zfcp_data.driver_version);
}
static DRIVER_ATTR(version, S_IRUGO, zfcp_sysfs_version_show, NULL);
......
......@@ -10,6 +10,7 @@
* Authors:
* Martin Peschke <mpeschke@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -26,7 +27,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_SYSFS_PORT_C_REVISION "$Revision: 1.44 $"
#define ZFCP_SYSFS_PORT_C_REVISION "$Revision: 1.46 $"
#include "zfcp_ext.h"
......
......@@ -10,6 +10,7 @@
* Authors:
* Martin Peschke <mpeschke@de.ibm.com>
* Heiko Carstens <heiko.carstens@de.ibm.com>
* Andreas Herrmann <aherrman@de.ibm.com>
*
* 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
......@@ -26,7 +27,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_SYSFS_UNIT_C_REVISION "$Revision: 1.27 $"
#define ZFCP_SYSFS_UNIT_C_REVISION "$Revision: 1.29 $"
#include "zfcp_ext.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment