Commit e1bc2047 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: zfcp host adapter

From: Heiko Carstens <heiko.carstens@de.ibm.com>
From: Andreas Herrmann <aherrman@de.ibm.com>
From: Maxim Shchetynin <maxim@de.ibm.com>

zfcp host adapter changes:
 - Exploit FC transport class and autoselect SCSI_FC_ATTRS for zfcp.
 - Fix acl download to zfcp controller.
 - Change message loglevels to make zfcp less noisy.
 - Don't wait for SBAL to finish for command aborts after a timeout
   and for logical unit or target resets.
 - Force reopen of port if link test failed.
 - Fix race between qdio_shutdown and do_QDIO.
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 6e955f71
...@@ -124,7 +124,7 @@ CONFIG_SCSI_LOGGING=y ...@@ -124,7 +124,7 @@ CONFIG_SCSI_LOGGING=y
# SCSI Transport Attributes # SCSI Transport Attributes
# #
# CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set CONFIG_SCSI_FC_ATTRS=y
# #
# SCSI low-level drivers # SCSI low-level drivers
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
*/ */
/* this drivers version (do not edit !!! generated and updated by cvs) */ /* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_AUX_REVISION "$Revision: 1.108 $" #define ZFCP_AUX_REVISION "$Revision: 1.114 $"
#include "zfcp_ext.h" #include "zfcp_ext.h"
...@@ -310,6 +310,10 @@ zfcp_module_init(void) ...@@ -310,6 +310,10 @@ zfcp_module_init(void)
/* initialize adapters to be removed list head */ /* initialize adapters to be removed list head */
INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh); INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh);
zfcp_transport_template = fc_attach_transport(&zfcp_transport_functions);
if (!zfcp_transport_template)
return -ENODEV;
#ifdef CONFIG_S390_SUPPORT #ifdef CONFIG_S390_SUPPORT
retval = register_ioctl32_conversion(zfcp_ioctl_trans.cmd, retval = register_ioctl32_conversion(zfcp_ioctl_trans.cmd,
zfcp_ioctl_trans.handler); zfcp_ioctl_trans.handler);
...@@ -414,7 +418,7 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file, ...@@ -414,7 +418,7 @@ zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file,
retval = -ENOMEM; retval = -ENOMEM;
goto out; goto out;
} }
sg_list->count = 0; memset(sg_list, 0, sizeof(*sg_list));
if (command != ZFCP_CFDC_IOC) { if (command != ZFCP_CFDC_IOC) {
ZFCP_LOG_INFO("IOC request code 0x%x invalid\n", command); ZFCP_LOG_INFO("IOC request code 0x%x invalid\n", command);
...@@ -599,6 +603,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size) ...@@ -599,6 +603,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
sg_list->sg = kmalloc(sg_list->count * sizeof(struct scatterlist), sg_list->sg = kmalloc(sg_list->count * sizeof(struct scatterlist),
GFP_KERNEL); GFP_KERNEL);
if (sg_list->sg == NULL) { if (sg_list->sg == NULL) {
sg_list->count = 0;
retval = -ENOMEM; retval = -ENOMEM;
goto out; goto out;
} }
...@@ -635,11 +640,13 @@ zfcp_sg_list_free(struct zfcp_sg_list *sg_list) ...@@ -635,11 +640,13 @@ zfcp_sg_list_free(struct zfcp_sg_list *sg_list)
unsigned int i; unsigned int i;
int retval = 0; int retval = 0;
BUG_ON((sg_list->sg == NULL) || (sg_list == NULL)); BUG_ON(sg_list == NULL);
for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++)
__free_pages(sg->page, 0); __free_pages(sg->page, 0);
kfree(sg_list->sg);
return retval; return retval;
} }
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define ZFCP_DEF_H #define ZFCP_DEF_H
/* this drivers version (do not edit !!! generated and updated by cvs) */ /* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_DEF_REVISION "$Revision: 1.73 $" #define ZFCP_DEF_REVISION "$Revision: 1.75 $"
/*************************** INCLUDES *****************************************/ /*************************** INCLUDES *****************************************/
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_fc.h>
#include "../../fc4/fc.h" #include "../../fc4/fc.h"
#include "zfcp_fsf.h" #include "zfcp_fsf.h"
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
...@@ -509,14 +511,14 @@ struct zfcp_ls_rnid_acc { ...@@ -509,14 +511,14 @@ struct zfcp_ls_rnid_acc {
/* all log-level defaults are combined to generate initial log-level */ /* all log-level defaults are combined to generate initial log-level */
#define ZFCP_LOG_LEVEL_DEFAULTS \ #define ZFCP_LOG_LEVEL_DEFAULTS \
(ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_OTHER) | \ (ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_OTHER) | \
ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_SCSI) | \ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_SCSI) | \
ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_FSF) | \ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FSF) | \
ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_CONFIG) | \ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CONFIG) | \
ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_CIO) | \ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CIO) | \
ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_QDIO) | \ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_QDIO) | \
ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_ERP) | \ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_ERP) | \
ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_FC)) ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FC))
/* check whether we have the right level for logging */ /* check whether we have the right level for logging */
#define ZFCP_LOG_CHECK(level) \ #define ZFCP_LOG_CHECK(level) \
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP #define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP
/* this drivers version (do not edit !!! generated and updated by cvs) */ /* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_ERP_REVISION "$Revision: 1.54 $" #define ZFCP_ERP_REVISION "$Revision: 1.56 $"
#include "zfcp_ext.h" #include "zfcp_ext.h"
...@@ -435,8 +435,20 @@ zfcp_els_handler(unsigned long data) ...@@ -435,8 +435,20 @@ zfcp_els_handler(unsigned long data)
u8 req_code, resp_code; u8 req_code, resp_code;
int retval = 0; int retval = 0;
if (send_els->status != 0) if (send_els->status != 0) {
ZFCP_LOG_NORMAL("ELS request timed out, physical port reopen "
"of port 0x%016Lx on adapter %s failed\n",
port->wwpn, zfcp_get_busid_by_port(port));
debug_text_event(port->adapter->erp_dbf, 3, "forcreop");
retval = zfcp_erp_port_forced_reopen(port, 0);
if (retval != 0) {
ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx "
"on adapter %s failed\n", port->wwpn,
zfcp_get_busid_by_port(port));
retval = -EPERM;
}
goto skip_fsfstatus; goto skip_fsfstatus;
}
req = (void*)((page_to_pfn(send_els->req->page) << PAGE_SHIFT) + send_els->req->offset); req = (void*)((page_to_pfn(send_els->req->page) << PAGE_SHIFT) + send_els->req->offset);
resp = (void*)((page_to_pfn(send_els->resp->page) << PAGE_SHIFT) + send_els->resp->offset); resp = (void*)((page_to_pfn(send_els->resp->page) << PAGE_SHIFT) + send_els->resp->offset);
...@@ -2286,7 +2298,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) ...@@ -2286,7 +2298,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
int i; int i;
volatile struct qdio_buffer_element *sbale; volatile struct qdio_buffer_element *sbale;
struct zfcp_adapter *adapter = erp_action->adapter; struct zfcp_adapter *adapter = erp_action->adapter;
int retval_cleanup = 0;
if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) { if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on " ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on "
...@@ -2301,7 +2312,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) ...@@ -2301,7 +2312,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
goto failed_qdio_establish; goto failed_qdio_establish;
} }
ZFCP_LOG_DEBUG("queues established\n"); debug_text_event(adapter->erp_dbf, 3, "qdio_est");
if (qdio_activate(adapter->ccw_device, 0) != 0) { if (qdio_activate(adapter->ccw_device, 0) != 0) {
ZFCP_LOG_INFO("error: activation of QDIO queues failed " ZFCP_LOG_INFO("error: activation of QDIO queues failed "
...@@ -2309,7 +2320,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) ...@@ -2309,7 +2320,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
goto failed_qdio_activate; goto failed_qdio_activate;
} }
ZFCP_LOG_DEBUG("queues activated\n"); debug_text_event(adapter->erp_dbf, 3, "qdio_act");
/* /*
* put buffers into response queue, * put buffers into response queue,
...@@ -2357,19 +2368,15 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) ...@@ -2357,19 +2368,15 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
/* NOP */ /* NOP */
failed_qdio_activate: failed_qdio_activate:
/* DEBUG */ debug_text_event(adapter->erp_dbf, 3, "qdio_down1a");
//__ZFCP_WAIT_EVENT_TIMEOUT(timeout, 0); while (qdio_shutdown(adapter->ccw_device,
/* cleanup queues previously established */ QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) {
retval_cleanup = qdio_shutdown(adapter->ccw_device, set_current_state(TASK_UNINTERRUPTIBLE);
QDIO_FLAG_CLEANUP_USING_CLEAR); schedule_timeout(HZ);
if (retval_cleanup) {
ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed "
"(retval=%d)\n", retval_cleanup);
} }
debug_text_event(adapter->erp_dbf, 3, "qdio_down1b");
failed_qdio_establish: failed_qdio_establish:
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
failed_sanity: failed_sanity:
retval = ZFCP_ERP_FAILED; retval = ZFCP_ERP_FAILED;
...@@ -2401,42 +2408,22 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) ...@@ -2401,42 +2408,22 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
goto out; goto out;
} }
/* cleanup queues previously established */
/*
* MUST NOT LOCK - qdio_cleanup might call schedule
* FIXME: need another way to make cleanup safe
*/
/* Note:
* We need the request_queue lock here, otherwise there exists the
* following race:
*
* queuecommand calls create_fcp_commmand_task...calls req_create,
* gets sbal x to x+y - meanwhile adapter reopen is called, completes
* - req_send calls do_QDIO for sbal x to x+y, i.e. wrong indices.
*
* with lock:
* queuecommand calls create_fcp_commmand_task...calls req_create,
* gets sbal x to x+y - meanwhile adapter reopen is called, waits
* - req_send calls do_QDIO for sbal x to x+y, i.e. wrong indices
* but do_QDIO fails as adapter_reopen is still waiting for the lock
* OR
* queuecommand calls create_fcp_commmand_task...calls req_create
* - meanwhile adapter reopen is called...completes,
* - gets sbal 0 to 0+y, - req_send calls do_QDIO for sbal 0 to 0+y,
* i.e. correct indices...though an fcp command is called before
* exchange config data...that should be fine, however
*/
if (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR)) {
/* /*
* FIXME(design): * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that
* What went wrong? What to do best? Proper retval? * do_QDIO won't be called while qdio_shutdown is in progress.
*/ */
ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed on "
"adapter %s\n", write_lock_irq(&adapter->request_queue.queue_lock);
zfcp_get_busid_by_adapter(adapter)); atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
} else write_unlock_irq(&adapter->request_queue.queue_lock);
ZFCP_LOG_DEBUG("queues cleaned up\n");
debug_text_event(adapter->erp_dbf, 3, "qdio_down2a");
while (qdio_shutdown(adapter->ccw_device,
QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ);
}
debug_text_event(adapter->erp_dbf, 3, "qdio_down2b");
/* /*
* First we had to stop QDIO operation. * First we had to stop QDIO operation.
...@@ -2459,8 +2446,6 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action) ...@@ -2459,8 +2446,6 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
adapter->request_queue.free_index = 0; adapter->request_queue.free_index = 0;
atomic_set(&adapter->request_queue.free_count, 0); atomic_set(&adapter->request_queue.free_count, 0);
adapter->request_queue.distance_from_int = 0; adapter->request_queue.distance_from_int = 0;
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
out: out:
return retval; return retval;
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#ifndef ZFCP_EXT_H #ifndef ZFCP_EXT_H
#define ZFCP_EXT_H #define ZFCP_EXT_H
/* this drivers version (do not edit !!! generated and updated by cvs) */ /* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_EXT_REVISION "$Revision: 1.50 $" #define ZFCP_EXT_REVISION "$Revision: 1.51 $"
#include "zfcp_def.h" #include "zfcp_def.h"
...@@ -136,6 +136,8 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *unit, ...@@ -136,6 +136,8 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *unit,
struct scsi_cmnd *scsi_cmnd); struct scsi_cmnd *scsi_cmnd);
extern int zfcp_scsi_command_sync(struct zfcp_unit *unit, extern int zfcp_scsi_command_sync(struct zfcp_unit *unit,
struct scsi_cmnd *scsi_cmnd); struct scsi_cmnd *scsi_cmnd);
extern struct scsi_transport_template *zfcp_transport_template;
extern struct fc_function_template zfcp_transport_functions;
/******************************** ERP ****************************************/ /******************************** ERP ****************************************/
extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int); extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int);
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
*/ */
/* this drivers version (do not edit !!! generated and updated by cvs) */ /* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_FSF_C_REVISION "$Revision: 1.47 $" #define ZFCP_FSF_C_REVISION "$Revision: 1.49 $"
#include "zfcp_ext.h" #include "zfcp_ext.h"
...@@ -3997,15 +3997,14 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) ...@@ -3997,15 +3997,14 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
scpnt->result |= fcp_rsp_iu->scsi_status; scpnt->result |= fcp_rsp_iu->scsi_status;
if (unlikely(fcp_rsp_iu->scsi_status)) { if (unlikely(fcp_rsp_iu->scsi_status)) {
/* DEBUG */ /* DEBUG */
ZFCP_LOG_NORMAL("status for SCSI Command:\n"); ZFCP_LOG_DEBUG("status for SCSI Command:\n");
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
scpnt->cmnd, scpnt->cmd_len); scpnt->cmnd, scpnt->cmd_len);
ZFCP_LOG_DEBUG("SCSI status code 0x%x\n",
ZFCP_LOG_NORMAL("SCSI status code 0x%x\n",
fcp_rsp_iu->scsi_status); fcp_rsp_iu->scsi_status);
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
(void *) fcp_rsp_iu, sizeof (struct fcp_rsp_iu)); (void *) fcp_rsp_iu, sizeof (struct fcp_rsp_iu));
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu),
fcp_rsp_iu->fcp_sns_len); fcp_rsp_iu->fcp_sns_len);
} }
...@@ -4782,6 +4781,16 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, ...@@ -4782,6 +4781,16 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
goto failed_sbals; goto failed_sbals;
} }
/*
* We hold queue_lock here. Check if QDIOUP is set and let request fail
* if it is not set (see also *_open_qdio and *_close_qdio).
*/
if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
write_unlock_irqrestore(&req_queue->queue_lock, *lock_flags);
goto failed_sbals;
}
fsf_req->adapter = adapter; /* pointer to "parent" adapter */ fsf_req->adapter = adapter; /* pointer to "parent" adapter */
fsf_req->fsf_command = fsf_cmd; fsf_req->fsf_command = fsf_cmd;
fsf_req->sbal_number = 1; fsf_req->sbal_number = 1;
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI #define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI
/* this drivers version (do not edit !!! generated and updated by cvs) */ /* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_SCSI_REVISION "$Revision: 1.62 $" #define ZFCP_SCSI_REVISION "$Revision: 1.65 $"
#include "zfcp_ext.h" #include "zfcp_ext.h"
...@@ -51,6 +51,8 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t, ...@@ -51,6 +51,8 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,
static struct device_attribute *zfcp_sysfs_sdev_attrs[]; static struct device_attribute *zfcp_sysfs_sdev_attrs[];
struct scsi_transport_template *zfcp_transport_template;
struct zfcp_data zfcp_data = { struct zfcp_data zfcp_data = {
.scsi_host_template = { .scsi_host_template = {
name: ZFCP_NAME, name: ZFCP_NAME,
...@@ -508,8 +510,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) ...@@ -508,8 +510,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
ZFCP_LOG_DEBUG("unit 0x%016Lx (%p)\n", unit->fcp_lun, unit); ZFCP_LOG_DEBUG("unit 0x%016Lx (%p)\n", unit->fcp_lun, unit);
/* /*
* The 'Abort FCP Command' routine may block (call schedule) * We block (call schedule)
* because it may wait for a free SBAL.
* That's why we must release the lock and enable the * That's why we must release the lock and enable the
* interrupts before. * interrupts before.
* On the other hand we do not need the lock anymore since * On the other hand we do not need the lock anymore since
...@@ -518,8 +519,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) ...@@ -518,8 +519,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
write_unlock_irqrestore(&adapter->abort_lock, flags); write_unlock_irqrestore(&adapter->abort_lock, flags);
/* call FSF routine which does the abort */ /* call FSF routine which does the abort */
new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req, new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req,
adapter, adapter, unit, 0);
unit, ZFCP_WAIT_FOR_SBAL);
ZFCP_LOG_DEBUG("new_fsf_req=%p\n", new_fsf_req); ZFCP_LOG_DEBUG("new_fsf_req=%p\n", new_fsf_req);
if (!new_fsf_req) { if (!new_fsf_req) {
retval = FAILED; retval = FAILED;
...@@ -657,7 +657,7 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags) ...@@ -657,7 +657,7 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags)
/* issue task management function */ /* issue task management function */
fsf_req = zfcp_fsf_send_fcp_command_task_management fsf_req = zfcp_fsf_send_fcp_command_task_management
(adapter, unit, tm_flags, ZFCP_WAIT_FOR_SBAL); (adapter, unit, tm_flags, 0);
if (!fsf_req) { if (!fsf_req) {
ZFCP_LOG_INFO("error: creation of task management request " ZFCP_LOG_INFO("error: creation of task management request "
"failed for unit 0x%016Lx on port 0x%016Lx on " "failed for unit 0x%016Lx on port 0x%016Lx on "
...@@ -768,6 +768,7 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) ...@@ -768,6 +768,7 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
adapter->scsi_host->max_channel = 0; adapter->scsi_host->max_channel = 0;
adapter->scsi_host->unique_id = unique_id++; /* FIXME */ adapter->scsi_host->unique_id = unique_id++; /* FIXME */
adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH; adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH;
adapter->scsi_host->transportt = zfcp_transport_template;
/* /*
* Reverse mapping of the host number to avoid race condition * Reverse mapping of the host number to avoid race condition
*/ */
...@@ -823,6 +824,44 @@ zfcp_fsf_start_scsi_er_timer(struct zfcp_adapter *adapter) ...@@ -823,6 +824,44 @@ zfcp_fsf_start_scsi_er_timer(struct zfcp_adapter *adapter)
add_timer(&adapter->scsi_er_timer); add_timer(&adapter->scsi_er_timer);
} }
/*
* Support functions for FC transport class
*/
static void
zfcp_get_port_id(struct scsi_device *sdev)
{
struct zfcp_unit *unit;
unit = (struct zfcp_unit *) sdev->hostdata;
fc_port_id(sdev) = unit->port->d_id;
}
static void
zfcp_get_port_name(struct scsi_device *sdev)
{
struct zfcp_unit *unit;
unit = (struct zfcp_unit *) sdev->hostdata;
fc_port_name(sdev) = unit->port->wwpn;
}
static void
zfcp_get_node_name(struct scsi_device *sdev)
{
struct zfcp_unit *unit;
unit = (struct zfcp_unit *) sdev->hostdata;
fc_node_name(sdev) = unit->port->wwnn;
}
struct fc_function_template zfcp_transport_functions = {
.get_port_id = zfcp_get_port_id,
.get_port_name = zfcp_get_port_name,
.get_node_name = zfcp_get_node_name,
.show_port_id = 1,
.show_port_name = 1,
.show_node_name = 1,
};
/** /**
* ZFCP_DEFINE_SCSI_ATTR * ZFCP_DEFINE_SCSI_ATTR
......
...@@ -1738,6 +1738,7 @@ config SCSI_SUNESP ...@@ -1738,6 +1738,7 @@ config SCSI_SUNESP
config ZFCP config ZFCP
tristate "FCP host bus adapter driver for IBM eServer zSeries" tristate "FCP host bus adapter driver for IBM eServer zSeries"
depends on ARCH_S390 && SCSI depends on ARCH_S390 && SCSI
select SCSI_FC_ATTRS
help help
If you want to access SCSI devices attached to your IBM eServer If you want to access SCSI devices attached to your IBM eServer
zSeries by means of Fibre Channel interfaces say Y. zSeries by means of Fibre Channel interfaces say Y.
......
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