* [PATCH] s390: zfcp host adapter.
@ 2004-07-27 14:53 Martin Schwidefsky
0 siblings, 0 replies; 3+ messages in thread
From: Martin Schwidefsky @ 2004-07-27 14:53 UTC (permalink / raw)
To: akpm, linux-kernel
[PATCH] s390: zfcp host adapter.
From: Heiko Carstens <heiko.carstens@de.ibm.com>
From: Maxim Shchetynin <maxim@de.ibm.com>
zfcp host adapter changes:
- Get rid of ZFCP_WAIT_EVENT_TIMEOUT macro.
- Correct an error log mesage.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diffstat:
drivers/s390/scsi/zfcp_def.h | 28 +---------------------------
drivers/s390/scsi/zfcp_erp.c | 11 +++--------
drivers/s390/scsi/zfcp_fsf.c | 12 ++++++------
3 files changed, 10 insertions(+), 41 deletions(-)
diff -urN linux-2.6/drivers/s390/scsi/zfcp_def.h linux-2.6-s390/drivers/s390/scsi/zfcp_def.h
--- linux-2.6/drivers/s390/scsi/zfcp_def.h Tue Jul 27 16:35:49 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_def.h Tue Jul 27 16:36:28 2004
@@ -33,7 +33,7 @@
#define ZFCP_DEF_H
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_DEF_REVISION "$Revision: 1.75 $"
+#define ZFCP_DEF_REVISION "$Revision: 1.78 $"
/*************************** INCLUDES *****************************************/
@@ -1125,32 +1125,6 @@
if (ZFCP_LOG_CHECK(level)) { \
_zfcp_hex_dump(addr, count); \
}
-/*
- * Not yet optimal but useful:
- * Waits until the condition is met or the timeout occurs.
- * The condition may be a function call. This allows to
- * execute some additional instructions in addition
- * to a simple condition check.
- * The timeout is modified on exit and holds the remaining time.
- * Thus it is zero if a timeout ocurred, i.e. the condition was
- * not met in the specified interval.
- */
-#define __ZFCP_WAIT_EVENT_TIMEOUT(timeout, condition) \
-do { \
- set_current_state(TASK_UNINTERRUPTIBLE); \
- while (!(condition) && timeout) \
- timeout = schedule_timeout(timeout); \
- current->state = TASK_RUNNING; \
-} while (0);
-
-#define ZFCP_WAIT_EVENT_TIMEOUT(waitqueue, timeout, condition) \
-do { \
- wait_queue_t entry; \
- init_waitqueue_entry(&entry, current); \
- add_wait_queue(&waitqueue, &entry); \
- __ZFCP_WAIT_EVENT_TIMEOUT(timeout, condition) \
- remove_wait_queue(&waitqueue, &entry); \
-} while (0);
#define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id)
#define zfcp_get_busid_by_port(port) (zfcp_get_busid_by_adapter(port->adapter))
diff -urN linux-2.6/drivers/s390/scsi/zfcp_erp.c linux-2.6-s390/drivers/s390/scsi/zfcp_erp.c
--- linux-2.6/drivers/s390/scsi/zfcp_erp.c Tue Jul 27 16:35:49 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_erp.c Tue Jul 27 16:36:28 2004
@@ -31,7 +31,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.56 $"
+#define ZFCP_ERP_REVISION "$Revision: 1.60 $"
#include "zfcp_ext.h"
@@ -436,8 +436,8 @@
int retval = 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",
+ ZFCP_LOG_NORMAL("ELS request timed out, force physical port "
+ "reopen of port 0x%016Lx on adapter %s\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);
@@ -2187,11 +2187,6 @@
ZFCP_LOG_INFO("Waiting to allow the adapter %s "
"to recover itself\n",
zfcp_get_busid_by_adapter(adapter));
- /*
- * SUGGESTION: substitute by
- * timeout = ZFCP_TYPE2_RECOVERY_TIME;
- * __ZFCP_WAIT_EVENT_TIMEOUT(timeout, 0);
- */
timeout = ZFCP_TYPE2_RECOVERY_TIME;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(timeout);
diff -urN linux-2.6/drivers/s390/scsi/zfcp_fsf.c linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.c
--- linux-2.6/drivers/s390/scsi/zfcp_fsf.c Tue Jul 27 16:36:28 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.c Tue Jul 27 16:36:28 2004
@@ -29,7 +29,7 @@
*/
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_FSF_C_REVISION "$Revision: 1.49 $"
+#define ZFCP_FSF_C_REVISION "$Revision: 1.53 $"
#include "zfcp_ext.h"
@@ -4717,14 +4717,14 @@
unsigned long *lock_flags)
{
int condition;
- unsigned long timeout = ZFCP_SBAL_TIMEOUT;
struct zfcp_qdio_queue *req_queue = &adapter->request_queue;
if (unlikely(req_flags & ZFCP_WAIT_FOR_SBAL)) {
- ZFCP_WAIT_EVENT_TIMEOUT(adapter->request_wq, timeout,
- (condition =
- (zfcp_fsf_req_create_sbal_check)
- (lock_flags, req_queue, 1)));
+ wait_event_interruptible_timeout(adapter->request_wq,
+ (condition =
+ zfcp_fsf_req_create_sbal_check
+ (lock_flags, req_queue, 1)),
+ ZFCP_SBAL_TIMEOUT);
if (!condition) {
return -EIO;
}
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH] s390: zfcp host adapter.
@ 2004-08-17 13:51 Martin Schwidefsky
0 siblings, 0 replies; 3+ messages in thread
From: Martin Schwidefsky @ 2004-08-17 13:51 UTC (permalink / raw)
To: akpm, linux-kernel
[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:
- Use predefined macro to create in_recovery sysfs attributes.
- Add function to check CT_IU response.
- Fix handling of rejected ELS commands.
- Change return value of zfcp_fsf_req_sbal_get to -ERESTARTSYS in some cases.
- Return proper error code if control file upload/download failed.
- Remove dead code.
- Avoid sparse warnings.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diffstat:
drivers/s390/scsi/zfcp_aux.c | 205 +++++++++++++++++++++++++++++---
drivers/s390/scsi/zfcp_def.h | 23 ++-
drivers/s390/scsi/zfcp_erp.c | 209 +++++++++------------------------
drivers/s390/scsi/zfcp_ext.h | 6
drivers/s390/scsi/zfcp_fsf.c | 121 ++-----------------
drivers/s390/scsi/zfcp_fsf.h | 4
drivers/s390/scsi/zfcp_scsi.c | 4
drivers/s390/scsi/zfcp_sysfs_adapter.c | 43 +-----
drivers/s390/scsi/zfcp_sysfs_driver.c | 4
drivers/s390/scsi/zfcp_sysfs_port.c | 33 -----
drivers/s390/scsi/zfcp_sysfs_unit.c | 29 ----
11 files changed, 311 insertions(+), 370 deletions(-)
diff -urN linux-2.6/drivers/s390/scsi/zfcp_aux.c linux-2.6-s390/drivers/s390/scsi/zfcp_aux.c
--- linux-2.6/drivers/s390/scsi/zfcp_aux.c Sat Aug 14 12:56:24 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_aux.c Tue Aug 17 14:38:21 2004
@@ -29,7 +29,7 @@
*/
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_AUX_REVISION "$Revision: 1.115 $"
+#define ZFCP_AUX_REVISION "$Revision: 1.121 $"
#include "zfcp_ext.h"
@@ -48,10 +48,10 @@
static inline int zfcp_sg_list_alloc(struct zfcp_sg_list *, size_t);
static inline int zfcp_sg_list_free(struct zfcp_sg_list *);
-static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *, void *,
- size_t);
-static inline int zfcp_sg_list_copy_to_user(void *, struct zfcp_sg_list *,
- size_t);
+static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *,
+ void __user *, size_t);
+static inline int zfcp_sg_list_copy_to_user(void __user *,
+ struct zfcp_sg_list *, size_t);
static int zfcp_cfdc_dev_ioctl(struct inode *, struct file *,
unsigned int, unsigned long);
@@ -95,7 +95,7 @@
module_param(loglevel, uint, 0);
MODULE_PARM_DESC(loglevel,
"log levels, 8 nibbles: "
- "(unassigned) ERP QDIO DIO Config FSF SCSI Other, "
+ "(unassigned) FC ERP QDIO CIO Config FSF SCSI Other, "
"levels: 0=none 1=normal 2=devel 3=trace");
#ifdef ZFCP_PRINT_FLAGS
@@ -382,7 +382,7 @@
zfcp_cfdc_dev_ioctl(struct inode *inode, struct file *file,
unsigned int command, unsigned long buffer)
{
- struct zfcp_cfdc_sense_data sense_data, *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;
@@ -403,7 +403,7 @@
goto out;
}
- if ((sense_data_user = (struct zfcp_cfdc_sense_data*)buffer) == NULL) {
+ if ((sense_data_user = (void __user *) buffer) == NULL) {
ZFCP_LOG_INFO("sense data record is required\n");
retval = -EINVAL;
goto out;
@@ -520,6 +520,12 @@
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)) {
+ retval = -ENXIO;
+ goto out;
+ }
+
sense_data.fsf_status = fsf_req->qtcb->header.fsf_status;
memcpy(&sense_data.fsf_status_qual,
&fsf_req->qtcb->header.fsf_status_qual,
@@ -637,7 +643,8 @@
* -EFAULT - Memory I/O operation fault
*/
static inline int
-zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list, void *user_buffer,
+zfcp_sg_list_copy_from_user(struct zfcp_sg_list *sg_list,
+ void __user *user_buffer,
size_t size)
{
struct scatterlist *sg;
@@ -671,7 +678,8 @@
* -EFAULT - Memory I/O operation fault
*/
static inline int
-zfcp_sg_list_copy_to_user(void *user_buffer, struct zfcp_sg_list *sg_list,
+zfcp_sg_list_copy_to_user(void __user *user_buffer,
+ struct zfcp_sg_list *sg_list,
size_t size)
{
struct scatterlist *sg;
@@ -1646,15 +1654,7 @@
ct_iu_req = zfcp_sg_to_address(ct->req);
ct_iu_resp = zfcp_sg_to_address(ct->resp);
- if (ct_iu_resp->header.revision != ZFCP_CT_REVISION)
- goto failed;
- if (ct_iu_resp->header.gs_type != ZFCP_CT_DIRECTORY_SERVICE)
- goto failed;
- if (ct_iu_resp->header.gs_subtype != ZFCP_CT_NAME_SERVER)
- goto failed;
- if (ct_iu_resp->header.options != ZFCP_CT_SYNCHRONOUS)
- goto failed;
- if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) {
+ if (zfcp_check_ct_response(&ct_iu_resp->header)) {
/* FIXME: do we need some specific erp entry points */
atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status);
goto failed;
@@ -1675,7 +1675,7 @@
zfcp_get_busid_by_port(port), port->wwpn, port->d_id);
goto out;
-failed:
+ failed:
ZFCP_LOG_NORMAL("warning: failed gid_pn nameserver request for wwpn "
"0x%016Lx for adapter %s\n",
port->wwpn, zfcp_get_busid_by_port(port));
@@ -1690,4 +1690,169 @@
return;
}
+/* reject CT_IU reason codes acc. to FC-GS-4 */
+static const struct zfcp_rc_entry zfcp_ct_rc[] = {
+ {0x01, "invalid command code"},
+ {0x02, "invalid version level"},
+ {0x03, "logical error"},
+ {0x04, "invalid CT_IU size"},
+ {0x05, "logical busy"},
+ {0x07, "protocol error"},
+ {0x09, "unable to perform command request"},
+ {0x0b, "command not supported"},
+ {0x0d, "server not available"},
+ {0x0e, "session could not be established"},
+ {0xff, "vendor specific error"},
+ {0, NULL},
+};
+
+/* LS_RJT reason codes acc. to FC-FS */
+static const struct zfcp_rc_entry zfcp_ls_rjt_rc[] = {
+ {0x01, "invalid LS_Command code"},
+ {0x03, "logical error"},
+ {0x05, "logical busy"},
+ {0x07, "protocol error"},
+ {0x09, "unable to perform command request"},
+ {0x0b, "command not supported"},
+ {0x0e, "command already in progress"},
+ {0xff, "vendor specific error"},
+ {0, NULL},
+};
+
+/* reject reason codes according to FC-PH/FC-FS */
+static const struct zfcp_rc_entry zfcp_p_rjt_rc[] = {
+ {0x01, "invalid D_ID"},
+ {0x02, "invalid S_ID"},
+ {0x03, "Nx_Port not available, temporary"},
+ {0x04, "Nx_Port not available, permament"},
+ {0x05, "class not supported"},
+ {0x06, "delimiter usage error"},
+ {0x07, "TYPE not supported"},
+ {0x08, "invalid Link_Control"},
+ {0x09, "invalid R_CTL field"},
+ {0x0a, "invalid F_CTL field"},
+ {0x0b, "invalid OX_ID"},
+ {0x0c, "invalid RX_ID"},
+ {0x0d, "invalid SEQ_ID"},
+ {0x0e, "invalid DF_CTL"},
+ {0x0f, "invalid SEQ_CNT"},
+ {0x10, "invalid parameter field"},
+ {0x11, "exchange error"},
+ {0x12, "protocol error"},
+ {0x13, "incorrect length"},
+ {0x14, "unsupported ACK"},
+ {0x15, "class of service not supported by entity at FFFFFE"},
+ {0x16, "login required"},
+ {0x17, "excessive sequences attempted"},
+ {0x18, "unable to establish exchange"},
+ {0x1a, "fabric path not available"},
+ {0x1b, "invalid VC_ID (class 4)"},
+ {0x1c, "invalid CS_CTL field"},
+ {0x1d, "insufficient resources for VC (class 4)"},
+ {0x1f, "invalid class of service"},
+ {0x20, "preemption request rejected"},
+ {0x21, "preemption not enabled"},
+ {0x22, "multicast error"},
+ {0x23, "multicast error terminate"},
+ {0x24, "process login required"},
+ {0xff, "vendor specific reject"},
+ {0, NULL},
+};
+
+/**
+ * zfcp_rc_description - return description for given reaon code
+ * @code: reason code
+ * @rc_table: table of reason codes and descriptions
+ */
+static inline const char *
+zfcp_rc_description(u8 code, const struct zfcp_rc_entry *rc_table)
+{
+ const char *descr = "unknown reason code";
+
+ do {
+ if (code == rc_table->code) {
+ descr = rc_table->description;
+ break;
+ }
+ rc_table++;
+ } while (rc_table->code && rc_table->description);
+
+ return descr;
+}
+
+/**
+ * zfcp_check_ct_response - evaluate reason code for CT_IU
+ * @rjt: response payload to an CT_IU request
+ * Return: 0 for accept CT_IU, 1 for reject CT_IU or invlid response code
+ */
+int
+zfcp_check_ct_response(struct ct_hdr *rjt)
+{
+ if (rjt->cmd_rsp_code == ZFCP_CT_ACCEPT)
+ return 0;
+
+ if (rjt->cmd_rsp_code != ZFCP_CT_REJECT) {
+ ZFCP_LOG_NORMAL("error: invalid Generic Service command/"
+ "response code (0x%04hx)\n",
+ rjt->cmd_rsp_code);
+ return 1;
+ }
+
+ ZFCP_LOG_INFO("Generic Service command rejected\n");
+ ZFCP_LOG_INFO("%s (0x%02x, 0x%02x, 0x%02x)\n",
+ zfcp_rc_description(rjt->reason_code, zfcp_ct_rc),
+ (u32) rjt->reason_code, (u32) rjt->reason_code_expl,
+ (u32) rjt->vendor_unique);
+
+ return 1;
+}
+
+/**
+ * zfcp_print_els_rjt - print reject parameter and description for ELS reject
+ * @rjt_par: reject parameter acc. to FC-PH/FC-FS
+ * @rc_table: table of reason codes and descriptions
+ */
+static inline void
+zfcp_print_els_rjt(struct zfcp_ls_rjt_par *rjt_par,
+ const struct zfcp_rc_entry *rc_table)
+{
+ ZFCP_LOG_INFO("%s (%02x %02x %02x %02x)\n",
+ zfcp_rc_description(rjt_par->reason_code, rc_table),
+ (u32) rjt_par->action, (u32) rjt_par->reason_code,
+ (u32) rjt_par->reason_expl, (u32) rjt_par->vendor_unique);
+}
+
+/**
+ * zfcp_fsf_handle_els_rjt - evaluate status qualifier/reason code on ELS reject
+ * @sq: status qualifier word
+ * @rjt_par: reject parameter as described in FC-PH and FC-FS
+ * Return: -EROMTEIO for LS_RJT, -EREMCHG for invalid D_ID, -EIO else
+ */
+int
+zfcp_handle_els_rjt(u32 sq, struct zfcp_ls_rjt_par *rjt_par)
+{
+ int ret = -EIO;
+
+ if (sq == FSF_IOSTAT_NPORT_RJT) {
+ ZFCP_LOG_INFO("ELS rejected (P_RJT)\n");
+ zfcp_print_els_rjt(rjt_par, zfcp_p_rjt_rc);
+ /* invalid d_id */
+ if (rjt_par->reason_code == 0x01)
+ ret = -EREMCHG;
+ } else if (sq == FSF_IOSTAT_FABRIC_RJT) {
+ ZFCP_LOG_INFO("ELS rejected (F_RJT)\n");
+ zfcp_print_els_rjt(rjt_par, zfcp_p_rjt_rc);
+ /* invalid d_id */
+ if (rjt_par->reason_code == 0x01)
+ ret = -EREMCHG;
+ } else if (sq == FSF_IOSTAT_LS_RJT) {
+ ZFCP_LOG_INFO("ELS rejected (LS_RJT)\n");
+ zfcp_print_els_rjt(rjt_par, zfcp_ls_rjt_rc);
+ ret = -EREMOTEIO;
+ } else
+ ZFCP_LOG_INFO("unexpected SQ: 0x%02x\n", sq);
+
+ return ret;
+}
+
#undef ZFCP_LOG_AREA
diff -urN linux-2.6/drivers/s390/scsi/zfcp_def.h linux-2.6-s390/drivers/s390/scsi/zfcp_def.h
--- linux-2.6/drivers/s390/scsi/zfcp_def.h Sat Aug 14 12:55:33 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_def.h Tue Aug 17 14:38:21 2004
@@ -33,7 +33,7 @@
#define ZFCP_DEF_H
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_DEF_REVISION "$Revision: 1.81 $"
+#define ZFCP_DEF_REVISION "$Revision: 1.83 $"
/*************************** INCLUDES *****************************************/
@@ -296,13 +296,11 @@
#define ZFCP_LS_RJT_COMMAND_NOT_SUPPORTED 0x0B
#define ZFCP_LS_RJT_VENDOR_UNIQUE_ERROR 0xFF
-struct zfcp_ls_rjt {
- u8 code;
- u8 field[3];
- u8 reserved;
- u8 reason_code;
- u8 reason_expl;
- u8 vendor_unique;
+struct zfcp_ls_rjt_par {
+ u8 action;
+ u8 reason_code;
+ u8 reason_expl;
+ u8 vendor_unique;
} __attribute__ ((packed));
struct zfcp_ls_rtv {
@@ -423,6 +421,11 @@
specific_id;
} __attribute__((packed));
+struct zfcp_rc_entry {
+ u8 code;
+ const char *description;
+};
+
/*
* FC-GS-2 stuff
*/
@@ -431,9 +434,9 @@
#define ZFCP_CT_NAME_SERVER 0x02
#define ZFCP_CT_SYNCHRONOUS 0x00
#define ZFCP_CT_GID_PN 0x0121
-#define ZFCP_CT_GA_NXT 0x0100
#define ZFCP_CT_MAX_SIZE 0x1020
#define ZFCP_CT_ACCEPT 0x8002
+#define ZFCP_CT_REJECT 0x8001
/*
* FC-GS-4 stuff
@@ -851,7 +854,7 @@
struct zfcp_port *port;
};
-typedef int (*zfcp_send_els_handler_t)(unsigned long);
+typedef void (*zfcp_send_els_handler_t)(unsigned long);
/* used to pass parameters to zfcp_send_els() */
/* ToDo merge send_ct() and send_els() and corresponding structs */
diff -urN linux-2.6/drivers/s390/scsi/zfcp_erp.c linux-2.6-s390/drivers/s390/scsi/zfcp_erp.c
--- linux-2.6/drivers/s390/scsi/zfcp_erp.c Sat Aug 14 12:54:51 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_erp.c Tue Aug 17 14:38:21 2004
@@ -31,12 +31,12 @@
#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.61 $"
+#define ZFCP_ERP_REVISION "$Revision: 1.62 $"
#include "zfcp_ext.h"
static int zfcp_els(struct zfcp_port *, u8);
-static int zfcp_els_handler(unsigned long);
+static void zfcp_els_handler(unsigned long);
static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int);
static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int);
@@ -324,6 +324,7 @@
send_els->completion = NULL;
req = zfcp_sg_to_address(send_els->req);
+ memset(req, 0, PAGE_SIZE);
*(u32*)req = 0;
*(u8*)req = ls_code;
@@ -412,185 +413,99 @@
}
-/*
- * function: zfcp_els_handler
- *
- * purpose: Handler for all kind of ELSs
- *
- * returns: 0 - Operation completed successfuly
- * -ENXIO - ELS has been rejected
- * -EPERM - Port forced reopen failed
+/**
+ * zfcp_els_handler - handler for ELS commands
+ * @data: pointer to struct zfcp_send_els
+ * If ELS failed (LS_RJT or timed out) forced reopen of the port is triggered.
*/
-int
+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_ls_rjt *rjt;
struct zfcp_ls_rtv_acc *rtv;
struct zfcp_ls_rls_acc *rls;
struct zfcp_ls_pdisc_acc *pdisc;
struct zfcp_ls_adisc_acc *adisc;
void *req, *resp;
- u8 req_code, resp_code;
- int retval = 0;
+ u8 req_code;
+ /* request rejected or timed out */
if (send_els->status != 0) {
ZFCP_LOG_NORMAL("ELS request timed out, force physical port "
"reopen of port 0x%016Lx on adapter %s\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) {
+ if (zfcp_erp_port_forced_reopen(port, 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 out;
}
- 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);
+ req = zfcp_sg_to_address(send_els->req);
+ resp = zfcp_sg_to_address(send_els->resp);
req_code = *(u8*)req;
- resp_code = *(u8*)resp;
-
- switch (resp_code) {
-
- case ZFCP_LS_RJT:
- rjt = (struct zfcp_ls_rjt*)resp;
- switch (rjt->reason_code) {
+ switch (req_code) {
- case ZFCP_LS_RJT_INVALID_COMMAND_CODE:
- ZFCP_LOG_INFO("invalid LS command code "
- "(wwpn=0x%016Lx, command=0x%02x)\n",
- port->wwpn, req_code);
- break;
-
- case ZFCP_LS_RJT_LOGICAL_ERROR:
- ZFCP_LOG_INFO("logical error (wwpn=0x%016Lx, "
- "reason_expl=0x%02x)\n",
- port->wwpn, rjt->reason_expl);
- break;
-
- case ZFCP_LS_RJT_LOGICAL_BUSY:
- ZFCP_LOG_INFO("logical busy (wwpn=0x%016Lx, "
- "reason_expl=0x%02x)\n",
- port->wwpn, rjt->reason_expl);
- break;
-
- case ZFCP_LS_RJT_PROTOCOL_ERROR:
- ZFCP_LOG_INFO("protocol error (wwpn=0x%016Lx, "
- "reason_expl=0x%02x)\n",
- port->wwpn, rjt->reason_expl);
- break;
-
- case ZFCP_LS_RJT_UNABLE_TO_PERFORM:
- ZFCP_LOG_INFO("unable to perform command requested "
- "(wwpn=0x%016Lx, reason_expl=0x%02x)\n",
- port->wwpn, rjt->reason_expl);
- break;
-
- case ZFCP_LS_RJT_COMMAND_NOT_SUPPORTED:
- ZFCP_LOG_INFO("command not supported (wwpn=0x%016Lx, "
- "command=0x%02x)\n",
- port->wwpn, req_code);
- break;
-
- case ZFCP_LS_RJT_VENDOR_UNIQUE_ERROR:
- ZFCP_LOG_INFO("vendor specific error (wwpn=0x%016Lx, "
- "vendor_unique=0x%02x)\n",
- port->wwpn, rjt->vendor_unique);
- break;
-
- default:
- ZFCP_LOG_NORMAL("ELS rejected by remote port 0x%016Lx "
- "on adapter %s (reason_code=0x%02x)\n",
- port->wwpn,
- zfcp_get_busid_by_port(port),
- rjt->reason_code);
- }
- retval = -ENXIO;
+ case ZFCP_LS_RTV:
+ rtv = (struct zfcp_ls_rtv_acc*)resp;
+ ZFCP_LOG_INFO("RTV response from d_id 0x%08x to s_id "
+ "0x%08x (R_A_TOV=%ds E_D_TOV=%d%cs)\n",
+ port->d_id, port->adapter->s_id,
+ rtv->r_a_tov, rtv->e_d_tov,
+ rtv->qualifier &
+ ZFCP_LS_RTV_E_D_TOV_FLAG ? 'n' : 'm');
break;
- case ZFCP_LS_ACC:
- switch (req_code) {
+ case ZFCP_LS_RLS:
+ rls = (struct zfcp_ls_rls_acc*)resp;
+ ZFCP_LOG_INFO("RLS response from d_id 0x%08x to s_id "
+ "0x%08x (link_failure_count=%u, "
+ "loss_of_sync_count=%u, "
+ "loss_of_signal_count=%u, "
+ "primitive_sequence_protocol_error=%u, "
+ "invalid_transmition_word=%u, "
+ "invalid_crc_count=%u)\n",
+ port->d_id, port->adapter->s_id,
+ rls->link_failure_count,
+ rls->loss_of_sync_count,
+ rls->loss_of_signal_count,
+ rls->prim_seq_prot_error,
+ rls->invalid_transmition_word,
+ rls->invalid_crc_count);
+ break;
- case ZFCP_LS_RTV:
- rtv = (struct zfcp_ls_rtv_acc*)resp;
- ZFCP_LOG_INFO("RTV response from d_id 0x%08x to s_id "
- "0x%08x (R_A_TOV=%ds E_D_TOV=%d%cs)\n",
- port->d_id, port->adapter->s_id,
- rtv->r_a_tov, rtv->e_d_tov,
- rtv->qualifier &
- ZFCP_LS_RTV_E_D_TOV_FLAG ? 'n' : 'm');
- break;
-
- case ZFCP_LS_RLS:
- rls = (struct zfcp_ls_rls_acc*)resp;
- ZFCP_LOG_INFO("RLS response from d_id 0x%08x to s_id "
- "0x%08x (link_failure_count=%u, "
- "loss_of_sync_count=%u, "
- "loss_of_signal_count=%u, "
- "primitive_sequence_protocol_error=%u, "
- "invalid_transmition_word=%u, "
- "invalid_crc_count=%u)\n",
- port->d_id, port->adapter->s_id,
- rls->link_failure_count,
- rls->loss_of_sync_count,
- rls->loss_of_signal_count,
- rls->prim_seq_prot_error,
- rls->invalid_transmition_word,
- rls->invalid_crc_count);
- break;
-
- case ZFCP_LS_PDISC:
- pdisc = (struct zfcp_ls_pdisc_acc*)resp;
- ZFCP_LOG_INFO("PDISC response from d_id 0x%08x to s_id "
- "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
- "vendor='%-16s')\n", port->d_id,
- port->adapter->s_id, pdisc->wwpn,
- pdisc->wwnn, pdisc->vendor_version);
- break;
-
- case ZFCP_LS_ADISC:
- adisc = (struct zfcp_ls_adisc_acc*)resp;
- ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "
- "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
- "hard_nport_id=0x%08x, "
- "nport_id=0x%08x)\n", port->d_id,
- port->adapter->s_id, adisc->wwpn,
- adisc->wwnn, adisc->hard_nport_id,
- adisc->nport_id);
- /* FIXME: set wwnn in during open port */
- if (port->wwnn == 0)
- port->wwnn = adisc->wwnn;
- break;
- }
+ case ZFCP_LS_PDISC:
+ pdisc = (struct zfcp_ls_pdisc_acc*)resp;
+ ZFCP_LOG_INFO("PDISC response from d_id 0x%08x to s_id "
+ "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
+ "vendor='%-16s')\n", port->d_id,
+ port->adapter->s_id, pdisc->wwpn,
+ pdisc->wwnn, pdisc->vendor_version);
break;
- default:
- ZFCP_LOG_NORMAL("unknown payload code 0x%02x received for "
- "request 0x%02x to d_id 0x%08x, reopen needed "
- "for port 0x%016Lx on adapter %s\n", resp_code,
- req_code, port->d_id, port->wwpn,
- zfcp_get_busid_by_port(port));
- 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;
- }
+ case ZFCP_LS_ADISC:
+ adisc = (struct zfcp_ls_adisc_acc*)resp;
+ ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "
+ "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
+ "hard_nport_id=0x%08x, "
+ "nport_id=0x%08x)\n", port->d_id,
+ port->adapter->s_id, adisc->wwpn,
+ adisc->wwnn, adisc->hard_nport_id,
+ adisc->nport_id);
+ /* FIXME: set wwnn in during open port */
+ if (port->wwnn == 0)
+ port->wwnn = adisc->wwnn;
+ break;
}
-skip_fsfstatus:
+ out:
__free_pages(send_els->req->page, 0);
kfree(send_els->req);
kfree(send_els->resp);
-
- return retval;
+ kfree(send_els);
}
diff -urN linux-2.6/drivers/s390/scsi/zfcp_ext.h linux-2.6-s390/drivers/s390/scsi/zfcp_ext.h
--- linux-2.6/drivers/s390/scsi/zfcp_ext.h Sat Aug 14 12:54:51 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_ext.h Tue Aug 17 14:38:21 2004
@@ -31,7 +31,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.51 $"
+#define ZFCP_EXT_REVISION "$Revision: 1.53 $"
#include "zfcp_def.h"
@@ -117,9 +117,11 @@
extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(
unsigned long, struct zfcp_adapter *, struct zfcp_unit *, int);
-/******************************** FCP ****************************************/
+/******************************* FC/FCP **************************************/
extern int zfcp_nameserver_enqueue(struct zfcp_adapter *);
extern int zfcp_ns_gid_pn_request(struct zfcp_erp_action *);
+extern int zfcp_check_ct_response(struct ct_hdr *);
+extern int zfcp_handle_els_rjt(u32, struct zfcp_ls_rjt_par *);
/******************************* SCSI ****************************************/
extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
diff -urN linux-2.6/drivers/s390/scsi/zfcp_fsf.c linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.c
--- linux-2.6/drivers/s390/scsi/zfcp_fsf.c Sat Aug 14 12:55:47 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.c Tue Aug 17 14:38:21 2004
@@ -29,7 +29,7 @@
*/
/* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_FSF_C_REVISION "$Revision: 1.55 $"
+#define ZFCP_FSF_C_REVISION "$Revision: 1.59 $"
#include "zfcp_ext.h"
@@ -48,7 +48,7 @@
static int zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *);
static int zfcp_fsf_control_file_handler(struct zfcp_fsf_req *);
-static inline int zfcp_fsf_req_create_sbal_check(
+static inline int zfcp_fsf_req_sbal_check(
unsigned long *, struct zfcp_qdio_queue *, int);
static inline int zfcp_use_one_sbal(
struct scatterlist *, int, struct scatterlist *, int);
@@ -79,10 +79,9 @@
};
static const char zfcp_act_subtable_type[5][8] = {
- {"unknown"}, {"OS"}, {"WWPN"}, {"DID"}, {"LUN"}
+ "unknown", "OS", "WWPN", "DID", "LUN"
};
-
/****************************************************************/
/*************** FSF related Functions *************************/
/****************************************************************/
@@ -1863,6 +1862,10 @@
/* ERP strategy will escalate */
debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp");
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
+ retval =
+ zfcp_handle_els_rjt(header->fsf_status_qual.word[1],
+ (struct zfcp_ls_rjt_par *)
+ &header->fsf_status_qual.word[2]);
break;
case FSF_SQ_RETRY_IF_POSSIBLE:
ZFCP_LOG_FLAGS(2, "FSF_SQ_RETRY_IF_POSSIBLE\n");
@@ -1971,8 +1974,6 @@
if (send_els->handler != 0)
send_els->handler(send_els->handler_data);
- kfree(send_els);
-
return retval;
}
@@ -4157,87 +4158,6 @@
}
skip_fsfstatus:
-#if 0
- /*
- * This nasty chop at the problem is not working anymore
- * as we do not adjust the retry count anylonger in order
- * to have a number of retries that avoids I/O errors.
- * The manipulation of the retry count has been removed
- * in favour of a safe tape device handling. We must not
- * sent SCSI commands more than once to a device if no
- * retries are permitted by the high level driver. Generally
- * speaking, it was a mess to change retry counts. So it is
- * fine that this sort of workaround is gone.
- * Then, we had to face a certain number of immediate retries in case of
- * busy and queue full conditions (see below).
- * This is not acceptable
- * for the latter. Queue full conditions are used
- * by devices to indicate to a host that the host can rely
- * on the completion (or timeout) of at least one outstanding
- * command as a suggested trigger for command retries.
- * Busy conditions require a different trigger since
- * no commands are outstanding for that initiator from the
- * devices perspective.
- * The drawback of mapping a queue full condition to a
- * busy condition is the chance of wasting all retries prior
- * to the time when the device indicates that a command
- * rejected due to a queue full condition should be re-driven.
- * This case would lead to unnecessary I/O errors that
- * have to be considered fatal if for example ext3's
- * journaling would be torpedoed by such an avoidable
- * I/O error.
- * So, what issues are there with not mapping a queue-full
- * condition to a busy condition?
- * Due to the 'exclusive LUN'
- * policy enforced by the zSeries FCP channel, this
- * Linux instance is the only initiator with regard to
- * this adapter. It is safe to rely on the information
- * 'don't disturb me now ... and btw. no other commands
- * pending for you' (= queue full) sent by the LU,
- * since no other Linux can use this LUN via this adapter
- * at the same time. If there is a potential race
- * introduced by the FCP channel by not inhibiting Linux A
- * to give up a LU with commands pending while Linux B
- * grabs this LU and sends commands - thus providing
- * an exploit at the 'exclusive LUN' policy - then this
- * issue has to be considered a hardware problem. It should
- * be tracked as such if it really occurs. Even if the
- * FCP Channel spec. begs exploiters to wait for the
- * completion of all request sent to a LU prior to
- * closing this LU connection.
- * This spec. statement in conjunction with
- * the 'exclusive LUN' policy is not consistent design.
- * Another issue is how resource constraints for SCSI commands
- * might be handled by the FCP channel (just guessing for now).
- * If the FCP channel would always map resource constraints,
- * e.g. no free FC exchange ID due to I/O stress caused by
- * other sharing Linux instances, to faked queue-full
- * conditions then this would be a misinterpretation and
- * violation of SCSI standards.
- * If there are SCSI stack races as indicated below
- * then they need to be fixed just there.
- * Providing all issue above are not applicable or will
- * be fixed appropriately, removing the following hack
- * is the right thing to do.
- */
-
- /*
- * Note: This is a rather nasty chop at the problem. We cannot
- * risk adding to the mlqueue however as this will block the
- * device. If it is the last outstanding command for this host
- * it will remain blocked indefinitely. This would be quite possible
- * on the zSeries FCP adapter.
- * Also, there exists a race with scsi_insert_special relying on
- * scsi_request_fn to recalculate some command data which may not
- * happen when q->plugged is true in scsi_request_fn
- */
- if (status_byte(scpnt->result) == QUEUE_FULL) {
- ZFCP_LOG_DEBUG("Changing QUEUE_FULL to BUSY....\n");
- scpnt->result &= ~(QUEUE_FULL << 1);
- scpnt->result |= (BUSY << 1);
- }
-#endif
-
ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result);
zfcp_cmd_dbf_event_scsi("response", scpnt);
@@ -4682,8 +4602,8 @@
}
static inline int
-zfcp_fsf_req_create_sbal_check(unsigned long *flags,
- struct zfcp_qdio_queue *queue, int needed)
+zfcp_fsf_req_sbal_check(unsigned long *flags,
+ struct zfcp_qdio_queue *queue, int needed)
{
write_lock_irqsave(&queue->queue_lock, *flags);
if (likely(atomic_read(&queue->free_count) >= needed))
@@ -4713,29 +4633,24 @@
* @adapter: adapter for which request queue is examined
* @req_flags: flags indicating whether to wait for needed SBAL or not
* @lock_flags: lock_flags is queue_lock is taken
- *
- * locking: on success the queue_lock for the request queue of the adapter
- * is held
+ * Return: 0 on success, otherwise -EIO, or -ERESTARTSYS
+ * Locks: lock adapter->request_queue->queue_lock on success
*/
static int
zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter, int req_flags,
unsigned long *lock_flags)
{
- int condition;
+ long ret;
struct zfcp_qdio_queue *req_queue = &adapter->request_queue;
if (unlikely(req_flags & ZFCP_WAIT_FOR_SBAL)) {
- wait_event_interruptible_timeout(adapter->request_wq,
- (condition =
- zfcp_fsf_req_create_sbal_check
- (lock_flags, req_queue, 1)),
- ZFCP_SBAL_TIMEOUT);
- if (!condition) {
- return -EIO;
- }
- } else if (!zfcp_fsf_req_create_sbal_check(lock_flags, req_queue, 1)) {
+ ret = wait_event_interruptible_timeout(adapter->request_wq,
+ zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1),
+ ZFCP_SBAL_TIMEOUT);
+ if (ret < 0)
+ return ret;
+ } else if (!zfcp_fsf_req_sbal_check(lock_flags, req_queue, 1))
return -EIO;
- }
return 0;
}
diff -urN linux-2.6/drivers/s390/scsi/zfcp_fsf.h linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.h
--- linux-2.6/drivers/s390/scsi/zfcp_fsf.h Sat Aug 14 12:56:00 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.h Tue Aug 17 14:38:21 2004
@@ -227,6 +227,10 @@
#define FSF_HBA_PORTSTATE_LINKDOWN 0x00000006
#define FSF_HBA_PORTSTATE_ERROR 0x00000007
+/* IO states of adapter */
+#define FSF_IOSTAT_NPORT_RJT 0x00000004
+#define FSF_IOSTAT_FABRIC_RJT 0x00000005
+#define FSF_IOSTAT_LS_RJT 0x00000009
struct fsf_queue_designator;
struct fsf_status_read_buffer;
diff -urN linux-2.6/drivers/s390/scsi/zfcp_scsi.c linux-2.6-s390/drivers/s390/scsi/zfcp_scsi.c
--- linux-2.6/drivers/s390/scsi/zfcp_scsi.c Sat Aug 14 12:56:26 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_scsi.c Tue Aug 17 14:38:21 2004
@@ -31,7 +31,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.65 $"
+#define ZFCP_SCSI_REVISION "$Revision: 1.66 $"
#include "zfcp_ext.h"
@@ -430,7 +430,7 @@
u64 dbf_fsf_req = 0;
u64 dbf_fsf_status = 0;
u64 dbf_fsf_qual[2] = { 0, 0 };
- char dbf_result[ZFCP_ABORT_DBF_LENGTH] = { "##undef" };
+ char dbf_result[ZFCP_ABORT_DBF_LENGTH] = "##undef";
memset(dbf_opcode, 0, ZFCP_ABORT_DBF_LENGTH);
memcpy(dbf_opcode,
diff -urN linux-2.6/drivers/s390/scsi/zfcp_sysfs_adapter.c linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_adapter.c
--- linux-2.6/drivers/s390/scsi/zfcp_sysfs_adapter.c Sat Aug 14 12:54:47 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_adapter.c Tue Aug 17 14:38:21 2004
@@ -26,18 +26,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define ZFCP_SYSFS_ADAPTER_C_REVISION "$Revision: 1.33 $"
+#define ZFCP_SYSFS_ADAPTER_C_REVISION "$Revision: 1.36 $"
#include "zfcp_ext.h"
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG
static const char fc_topologies[5][25] = {
- {"<error>"},
- {"point-to-point"},
- {"fabric"},
- {"arbitrated loop"},
- {"fabric (virt. adapter)"}
+ "<error>",
+ "point-to-point",
+ "fabric",
+ "arbitrated loop",
+ "fabric (virt. adapter)"
};
/**
@@ -74,29 +74,8 @@
adapter->hardware_version);
ZFCP_DEFINE_ADAPTER_ATTR(serial_number, "%17s\n", adapter->serial_number);
ZFCP_DEFINE_ADAPTER_ATTR(scsi_host_no, "0x%x\n", adapter->scsi_host_no);
-
-/**
- * zfcp_sysfs_adapter_in_recovery_show - recovery state of adapter
- * @dev: pointer to belonging device
- * @buf: pointer to input buffer
- *
- * Show function of "in_recovery" attribute of adapter. Will be
- * "0" if no error recovery is pending for adapter, otherwise "1".
- */
-static ssize_t
-zfcp_sysfs_adapter_in_recovery_show(struct device *dev, char *buf)
-{
- struct zfcp_adapter *adapter;
-
- adapter = dev_get_drvdata(dev);
- if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status))
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(in_recovery, S_IRUGO,
- zfcp_sysfs_adapter_in_recovery_show, NULL);
+ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask
+ (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status));
/**
* zfcp_sysfs_port_add_store - add a port to sysfs tree
@@ -138,7 +117,7 @@
zfcp_port_put(port);
out:
up(&zfcp_data.config_sema);
- return retval ? retval : count;
+ return retval ? retval : (ssize_t) count;
}
static DEVICE_ATTR(port_add, S_IWUSR, NULL, zfcp_sysfs_port_add_store);
@@ -197,7 +176,7 @@
zfcp_port_dequeue(port);
out:
up(&zfcp_data.config_sema);
- return retval ? retval : count;
+ return retval ? retval : (ssize_t) count;
}
static DEVICE_ATTR(port_remove, S_IWUSR, NULL, zfcp_sysfs_port_remove_store);
@@ -241,7 +220,7 @@
zfcp_erp_wait(adapter);
out:
up(&zfcp_data.config_sema);
- return retval ? retval : count;
+ return retval ? retval : (ssize_t) count;
}
/**
diff -urN linux-2.6/drivers/s390/scsi/zfcp_sysfs_driver.c linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_driver.c
--- linux-2.6/drivers/s390/scsi/zfcp_sysfs_driver.c Sat Aug 14 12:56:00 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_driver.c Tue Aug 17 14:38:21 2004
@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define ZFCP_SYSFS_DRIVER_C_REVISION "$Revision: 1.14 $"
+#define ZFCP_SYSFS_DRIVER_C_REVISION "$Revision: 1.15 $"
#include "zfcp_ext.h"
@@ -65,7 +65,7 @@
static ssize_t zfcp_sysfs_loglevel_##_name##_show(struct device_driver *dev, \
char *buf) \
{ \
- return sprintf(buf,"%d\n", \
+ return sprintf(buf,"%d\n", (unsigned int) \
ZFCP_GET_LOG_VALUE(ZFCP_LOG_AREA_##_define)); \
} \
\
diff -urN linux-2.6/drivers/s390/scsi/zfcp_sysfs_port.c linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_port.c
--- linux-2.6/drivers/s390/scsi/zfcp_sysfs_port.c Sat Aug 14 12:56:22 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_port.c Tue Aug 17 14:38:21 2004
@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define ZFCP_SYSFS_PORT_C_REVISION "$Revision: 1.41 $"
+#define ZFCP_SYSFS_PORT_C_REVISION "$Revision: 1.43 $"
#include "zfcp_ext.h"
@@ -66,6 +66,8 @@
ZFCP_DEFINE_PORT_ATTR(wwnn, "0x%016llx\n", port->wwnn);
ZFCP_DEFINE_PORT_ATTR(d_id, "0x%06x\n", port->d_id);
ZFCP_DEFINE_PORT_ATTR(scsi_id, "0x%x\n", port->scsi_id);
+ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask
+ (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status));
/**
* zfcp_sysfs_unit_add_store - add a unit to sysfs tree
@@ -107,7 +109,7 @@
zfcp_unit_put(unit);
out:
up(&zfcp_data.config_sema);
- return retval ? retval : count;
+ return retval ? retval : (ssize_t) count;
}
static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
@@ -164,7 +166,7 @@
zfcp_unit_dequeue(unit);
out:
up(&zfcp_data.config_sema);
- return retval ? retval : count;
+ return retval ? retval : (ssize_t) count;
}
static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
@@ -206,7 +208,7 @@
zfcp_erp_wait(port->adapter);
out:
up(&zfcp_data.config_sema);
- return retval ? retval : count;
+ return retval ? retval : (ssize_t) count;
}
/**
@@ -233,29 +235,6 @@
zfcp_sysfs_port_failed_store);
/**
- * zfcp_sysfs_port_in_recovery_show - recovery state of port
- * @dev: pointer to belonging device
- * @buf: pointer to input buffer
- *
- * Show function of "in_recovery" attribute of port. Will be
- * "0" if no error recovery is pending for port, otherwise "1".
- */
-static ssize_t
-zfcp_sysfs_port_in_recovery_show(struct device *dev, char *buf)
-{
- struct zfcp_port *port;
-
- port = dev_get_drvdata(dev);
- if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status))
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(in_recovery, S_IRUGO, zfcp_sysfs_port_in_recovery_show,
- NULL);
-
-/**
* zfcp_port_common_attrs
* sysfs attributes that are common for all kind of fc ports.
*/
diff -urN linux-2.6/drivers/s390/scsi/zfcp_sysfs_unit.c linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_unit.c
--- linux-2.6/drivers/s390/scsi/zfcp_sysfs_unit.c Sat Aug 14 12:56:26 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_sysfs_unit.c Tue Aug 17 14:38:21 2004
@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define ZFCP_SYSFS_UNIT_C_REVISION "$Revision: 1.25 $"
+#define ZFCP_SYSFS_UNIT_C_REVISION "$Revision: 1.27 $"
#include "zfcp_ext.h"
@@ -64,6 +64,8 @@
ZFCP_DEFINE_UNIT_ATTR(status, "0x%08x\n", atomic_read(&unit->status));
ZFCP_DEFINE_UNIT_ATTR(scsi_lun, "0x%x\n", unit->scsi_lun);
+ZFCP_DEFINE_UNIT_ATTR(in_recovery, "%d\n", atomic_test_mask
+ (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status));
/**
* zfcp_sysfs_unit_failed_store - failed state of unit
@@ -101,7 +103,7 @@
zfcp_erp_wait(unit->port->adapter);
out:
up(&zfcp_data.config_sema);
- return retval ? retval : count;
+ return retval ? retval : (ssize_t) count;
}
/**
@@ -127,29 +129,6 @@
static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_unit_failed_show,
zfcp_sysfs_unit_failed_store);
-/**
- * zfcp_sysfs_unit_in_recovery_show - recovery state of unit
- * @dev: pointer to belonging device
- * @buf: pointer to input buffer
- *
- * Show function of "in_recovery" attribute of unit. Will be
- * "0" if no error recovery is pending for unit, otherwise "1".
- */
-static ssize_t
-zfcp_sysfs_unit_in_recovery_show(struct device *dev, char *buf)
-{
- struct zfcp_unit *unit;
-
- unit = dev_get_drvdata(dev);
- if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status))
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(in_recovery, S_IRUGO, zfcp_sysfs_unit_in_recovery_show,
- NULL);
-
static struct attribute *zfcp_unit_attrs[] = {
&dev_attr_scsi_lun.attr,
&dev_attr_failed.attr,
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH] s390: zfcp host adapter.
@ 2004-06-30 17:09 Martin Schwidefsky
0 siblings, 0 replies; 3+ messages in thread
From: Martin Schwidefsky @ 2004-06-30 17:09 UTC (permalink / raw)
To: akpm, linux-kernel
[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: Martin Schwidefsky <schwidefsky@de.ibm.com>
diffstat:
arch/s390/defconfig | 2
drivers/s390/scsi/zfcp_aux.c | 13 ++++--
drivers/s390/scsi/zfcp_def.h | 20 +++++----
drivers/s390/scsi/zfcp_erp.c | 87 +++++++++++++++++-------------------------
drivers/s390/scsi/zfcp_ext.h | 4 +
drivers/s390/scsi/zfcp_fsf.c | 23 +++++++----
drivers/s390/scsi/zfcp_scsi.c | 51 +++++++++++++++++++++---
drivers/scsi/Kconfig | 1
8 files changed, 123 insertions(+), 78 deletions(-)
diff -urN linux-2.6/arch/s390/defconfig linux-2.6-s390/arch/s390/defconfig
--- linux-2.6/arch/s390/defconfig Wed Jun 30 17:06:35 2004
+++ linux-2.6-s390/arch/s390/defconfig Wed Jun 30 17:06:38 2004
@@ -124,7 +124,7 @@
# SCSI Transport Attributes
#
# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=y
#
# SCSI low-level drivers
diff -urN linux-2.6/drivers/s390/scsi/zfcp_aux.c linux-2.6-s390/drivers/s390/scsi/zfcp_aux.c
--- linux-2.6/drivers/s390/scsi/zfcp_aux.c Wed Jun 16 07:20:26 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_aux.c Wed Jun 30 17:06:38 2004
@@ -29,7 +29,7 @@
*/
/* 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"
@@ -310,6 +310,10 @@
/* initialize adapters to be removed list head */
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
retval = register_ioctl32_conversion(zfcp_ioctl_trans.cmd,
zfcp_ioctl_trans.handler);
@@ -414,7 +418,7 @@
retval = -ENOMEM;
goto out;
}
- sg_list->count = 0;
+ memset(sg_list, 0, sizeof(*sg_list));
if (command != ZFCP_CFDC_IOC) {
ZFCP_LOG_INFO("IOC request code 0x%x invalid\n", command);
@@ -599,6 +603,7 @@
sg_list->sg = kmalloc(sg_list->count * sizeof(struct scatterlist),
GFP_KERNEL);
if (sg_list->sg == NULL) {
+ sg_list->count = 0;
retval = -ENOMEM;
goto out;
}
@@ -635,11 +640,13 @@
unsigned int i;
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++)
__free_pages(sg->page, 0);
+ kfree(sg_list->sg);
+
return retval;
}
diff -urN linux-2.6/drivers/s390/scsi/zfcp_def.h linux-2.6-s390/drivers/s390/scsi/zfcp_def.h
--- linux-2.6/drivers/s390/scsi/zfcp_def.h Wed Jun 16 07:19:36 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_def.h Wed Jun 30 17:06:38 2004
@@ -33,7 +33,7 @@
#define ZFCP_DEF_H
/* 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 *****************************************/
@@ -47,6 +47,8 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
#include "../../fc4/fc.h"
#include "zfcp_fsf.h"
#include <asm/ccwdev.h>
@@ -509,14 +511,14 @@
/* all log-level defaults are combined to generate initial log-level */
#define ZFCP_LOG_LEVEL_DEFAULTS \
- (ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_OTHER) | \
- ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_SCSI) | \
- ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_FSF) | \
- ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_CONFIG) | \
- ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_CIO) | \
- ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, ZFCP_LOG_AREA_QDIO) | \
- ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_INFO, 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_OTHER) | \
+ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_SCSI) | \
+ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FSF) | \
+ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CONFIG) | \
+ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_CIO) | \
+ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_QDIO) | \
+ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_ERP) | \
+ ZFCP_SET_LOG_NIBBLE(ZFCP_LOG_LEVEL_NORMAL, ZFCP_LOG_AREA_FC))
/* check whether we have the right level for logging */
#define ZFCP_LOG_CHECK(level) \
diff -urN linux-2.6/drivers/s390/scsi/zfcp_erp.c linux-2.6-s390/drivers/s390/scsi/zfcp_erp.c
--- linux-2.6/drivers/s390/scsi/zfcp_erp.c Wed Jun 16 07:19:01 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_erp.c Wed Jun 30 17:06:38 2004
@@ -31,7 +31,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.54 $"
+#define ZFCP_ERP_REVISION "$Revision: 1.56 $"
#include "zfcp_ext.h"
@@ -435,8 +435,20 @@
u8 req_code, resp_code;
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;
+ }
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);
@@ -2286,7 +2298,6 @@
int i;
volatile struct qdio_buffer_element *sbale;
struct zfcp_adapter *adapter = erp_action->adapter;
- int retval_cleanup = 0;
if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on "
@@ -2301,7 +2312,7 @@
zfcp_get_busid_by_adapter(adapter));
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) {
ZFCP_LOG_INFO("error: activation of QDIO queues failed "
@@ -2309,7 +2320,7 @@
zfcp_get_busid_by_adapter(adapter));
goto failed_qdio_activate;
}
- ZFCP_LOG_DEBUG("queues activated\n");
+ debug_text_event(adapter->erp_dbf, 3, "qdio_act");
/*
* put buffers into response queue,
@@ -2357,19 +2368,15 @@
/* NOP */
failed_qdio_activate:
- /* DEBUG */
- //__ZFCP_WAIT_EVENT_TIMEOUT(timeout, 0);
- /* cleanup queues previously established */
- retval_cleanup = qdio_shutdown(adapter->ccw_device,
- QDIO_FLAG_CLEANUP_USING_CLEAR);
- 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_down1a");
+ 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_down1b");
failed_qdio_establish:
- atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-
failed_sanity:
retval = ZFCP_ERP_FAILED;
@@ -2401,42 +2408,22 @@
goto out;
}
- /* cleanup queues previously established */
-
/*
- * MUST NOT LOCK - qdio_cleanup might call schedule
- * FIXME: need another way to make cleanup safe
+ * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that
+ * do_QDIO won't be called while qdio_shutdown is in progress.
*/
- /* 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):
- * What went wrong? What to do best? Proper retval?
- */
- ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed on "
- "adapter %s\n",
- zfcp_get_busid_by_adapter(adapter));
- } else
- ZFCP_LOG_DEBUG("queues cleaned up\n");
+
+ write_lock_irq(&adapter->request_queue.queue_lock);
+ atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
+ write_unlock_irq(&adapter->request_queue.queue_lock);
+
+ 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.
@@ -2459,8 +2446,6 @@
adapter->request_queue.free_index = 0;
atomic_set(&adapter->request_queue.free_count, 0);
adapter->request_queue.distance_from_int = 0;
-
- atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
out:
return retval;
}
diff -urN linux-2.6/drivers/s390/scsi/zfcp_ext.h linux-2.6-s390/drivers/s390/scsi/zfcp_ext.h
--- linux-2.6/drivers/s390/scsi/zfcp_ext.h Wed Jun 16 07:19:01 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_ext.h Wed Jun 30 17:06:38 2004
@@ -31,7 +31,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.50 $"
+#define ZFCP_EXT_REVISION "$Revision: 1.51 $"
#include "zfcp_def.h"
@@ -136,6 +136,8 @@
struct scsi_cmnd *scsi_cmnd);
extern int zfcp_scsi_command_sync(struct zfcp_unit *unit,
struct scsi_cmnd *scsi_cmnd);
+extern struct scsi_transport_template *zfcp_transport_template;
+extern struct fc_function_template zfcp_transport_functions;
/******************************** ERP ****************************************/
extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int);
diff -urN linux-2.6/drivers/s390/scsi/zfcp_fsf.c linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.c
--- linux-2.6/drivers/s390/scsi/zfcp_fsf.c Wed Jun 16 07:19:43 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_fsf.c Wed Jun 30 17:06:38 2004
@@ -29,7 +29,7 @@
*/
/* 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"
@@ -3997,15 +3997,14 @@
scpnt->result |= fcp_rsp_iu->scsi_status;
if (unlikely(fcp_rsp_iu->scsi_status)) {
/* DEBUG */
- ZFCP_LOG_NORMAL("status for SCSI Command:\n");
- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
+ ZFCP_LOG_DEBUG("status for SCSI Command:\n");
+ ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
scpnt->cmnd, scpnt->cmd_len);
-
- ZFCP_LOG_NORMAL("SCSI status code 0x%x\n",
+ ZFCP_LOG_DEBUG("SCSI status code 0x%x\n",
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));
- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
+ ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu),
fcp_rsp_iu->fcp_sns_len);
}
@@ -4782,6 +4781,16 @@
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->fsf_command = fsf_cmd;
fsf_req->sbal_number = 1;
diff -urN linux-2.6/drivers/s390/scsi/zfcp_scsi.c linux-2.6-s390/drivers/s390/scsi/zfcp_scsi.c
--- linux-2.6/drivers/s390/scsi/zfcp_scsi.c Wed Jun 16 07:19:17 2004
+++ linux-2.6-s390/drivers/s390/scsi/zfcp_scsi.c Wed Jun 30 17:06:38 2004
@@ -31,7 +31,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.62 $"
+#define ZFCP_SCSI_REVISION "$Revision: 1.65 $"
#include "zfcp_ext.h"
@@ -51,6 +51,8 @@
static struct device_attribute *zfcp_sysfs_sdev_attrs[];
+struct scsi_transport_template *zfcp_transport_template;
+
struct zfcp_data zfcp_data = {
.scsi_host_template = {
name: ZFCP_NAME,
@@ -508,8 +510,7 @@
ZFCP_LOG_DEBUG("unit 0x%016Lx (%p)\n", unit->fcp_lun, unit);
/*
- * The 'Abort FCP Command' routine may block (call schedule)
- * because it may wait for a free SBAL.
+ * We block (call schedule)
* That's why we must release the lock and enable the
* interrupts before.
* On the other hand we do not need the lock anymore since
@@ -518,8 +519,7 @@
write_unlock_irqrestore(&adapter->abort_lock, flags);
/* call FSF routine which does the abort */
new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req,
- adapter,
- unit, ZFCP_WAIT_FOR_SBAL);
+ adapter, unit, 0);
ZFCP_LOG_DEBUG("new_fsf_req=%p\n", new_fsf_req);
if (!new_fsf_req) {
retval = FAILED;
@@ -657,7 +657,7 @@
/* issue task management function */
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) {
ZFCP_LOG_INFO("error: creation of task management request "
"failed for unit 0x%016Lx on port 0x%016Lx on "
@@ -768,6 +768,7 @@
adapter->scsi_host->max_channel = 0;
adapter->scsi_host->unique_id = unique_id++; /* FIXME */
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
*/
@@ -823,6 +824,44 @@
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
diff -urN linux-2.6/drivers/scsi/Kconfig linux-2.6-s390/drivers/scsi/Kconfig
--- linux-2.6/drivers/scsi/Kconfig Wed Jun 30 17:06:16 2004
+++ linux-2.6-s390/drivers/scsi/Kconfig Wed Jun 30 17:06:38 2004
@@ -1738,6 +1738,7 @@
config ZFCP
tristate "FCP host bus adapter driver for IBM eServer zSeries"
depends on ARCH_S390 && SCSI
+ select SCSI_FC_ATTRS
help
If you want to access SCSI devices attached to your IBM eServer
zSeries by means of Fibre Channel interfaces say Y.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2004-08-17 13:55 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-27 14:53 [PATCH] s390: zfcp host adapter Martin Schwidefsky
-- strict thread matches above, loose matches on Subject: below --
2004-08-17 13:51 Martin Schwidefsky
2004-06-30 17:09 Martin Schwidefsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®