Commit f9a56f8a authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] s390: zfcp fixes (without kfree hack)

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

zfcp host adapter fixes:
 - Reuse freed scsi_ids and scsi_luns for mappings.
 - Order list of ports/units by assigned scsi_id/scsi_lun.
 - Don't update max_id/max_lun in scsi_host anymore.
 - Get rid of all magics.
 - Add owner field to ccw_driver structure.
 - Avoid deadlock on bus->subsys.rwsem.
 - Use a macro for all scsi device sysfs attributes.
 - Change proc_name from "dummy" to "zfcp".
 - Don't wait for scsi_add_device to complete while holding a semaphore.
 - Cleanup include files in zfcp_aux.c & zfcp_def.h.
 - Get rid of zfcp_erp_fsf_req_handler.
 - Proper link up/down handling.
 - Avoid possible NULL pointer dereference in zfcp_erp_schedule_work.
 - Remove module_exit function. Without an external release function for
   the zfcp_port/zfcp_unit objects module unloading is racy.
parent d959cc9f
This diff is collapsed.
......@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_CCW_C_REVISION "$Revision: 1.48 $"
#define ZFCP_CCW_C_REVISION "$Revision: 1.52 $"
#include <linux/init.h>
#include <linux/module.h>
......@@ -55,6 +55,7 @@ static struct ccw_device_id zfcp_ccw_device_id[] = {
};
static struct ccw_driver zfcp_ccw_driver = {
.owner = THIS_MODULE,
.name = ZFCP_NAME,
.ids = zfcp_ccw_device_id,
.probe = zfcp_ccw_probe,
......@@ -130,14 +131,9 @@ zfcp_ccw_remove(struct ccw_device *ccw_device)
list_for_each_entry_safe(port, p, &adapter->port_remove_lh, list) {
list_for_each_entry_safe(unit, u, &port->unit_remove_lh, list) {
zfcp_unit_wait(unit);
zfcp_sysfs_unit_remove_files(&unit->sysfs_device);
device_unregister(&unit->sysfs_device);
zfcp_unit_dequeue(unit);
}
zfcp_port_wait(port);
zfcp_sysfs_port_remove_files(&port->sysfs_device,
atomic_read(&port->status));
device_unregister(&port->sysfs_device);
zfcp_port_dequeue(port);
}
zfcp_adapter_wait(adapter);
zfcp_adapter_dequeue(adapter);
......@@ -163,13 +159,16 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(&ccw_device->dev);
retval = zfcp_adapter_debug_register(adapter);
if (retval)
goto out;
retval = zfcp_erp_thread_setup(adapter);
if (retval) {
ZFCP_LOG_INFO("error: out of resources. "
"error recovery thread for adapter %s "
"could not be started\n",
zfcp_get_busid_by_adapter(adapter));
goto out;
goto out_erp_thread;
}
retval = zfcp_adapter_scsi_register(adapter);
......@@ -183,6 +182,8 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
out_scsi_register:
zfcp_erp_thread_kill(adapter);
out_erp_thread:
zfcp_adapter_debug_unregister(adapter);
out:
up(&zfcp_data.config_sema);
return retval;
......@@ -208,6 +209,7 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
zfcp_erp_wait(adapter);
zfcp_adapter_scsi_unregister(adapter);
zfcp_erp_thread_kill(adapter);
zfcp_adapter_debug_unregister(adapter);
up(&zfcp_data.config_sema);
return 0;
}
......
......@@ -33,25 +33,29 @@
#define ZFCP_DEF_H
/* this drivers version (do not edit !!! generated and updated by cvs) */
#define ZFCP_DEF_REVISION "$Revision: 1.62 $"
#define ZFCP_DEF_REVISION "$Revision: 1.71 $"
/*************************** INCLUDES *****************************************/
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/miscdevice.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <scsi/scsi.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include "../../scsi/scsi.h"
#include "../../fc4/fc.h"
#include "zfcp_fsf.h" /* FSF SW Interface */
#include "zfcp_fsf.h"
#include <asm/ccwdev.h>
#include <asm/qdio.h>
#include <asm/debug.h>
#include <asm/ebcdic.h>
#include <linux/reboot.h>
#include <linux/mempool.h>
#include <linux/syscalls.h>
#include <linux/ioctl.h>
#ifdef CONFIG_S390_SUPPORT
#include <linux/ioctl32.h>
......@@ -60,10 +64,6 @@
/************************ DEBUG FLAGS *****************************************/
#define ZFCP_PRINT_FLAGS
#define ZFCP_DEBUG_REQUESTS /* fsf_req tracing */
#define ZFCP_DEBUG_COMMANDS /* host_byte tracing */
#define ZFCP_DEBUG_ABORTS /* scsi_cmnd abort tracing */
#define ZFCP_DEBUG_INCOMING_ELS /* incoming ELS tracing */
#define ZFCP_STAT_REQSIZES
#define ZFCP_STAT_QUEUES
......@@ -723,11 +723,6 @@ struct zfcp_cfdc_sense_data {
#define ZFCP_CFDC_MAX_CONTROL_FILE_SIZE 127 * 1024
static const char zfcp_act_subtable_type[5][8] = {
{"unknown"}, {"OS"}, {"WWPN"}, {"DID"}, {"LUN"}
};
/************************* STRUCTURE DEFINITIONS *****************************/
struct zfcp_fsf_req;
......@@ -937,8 +932,6 @@ struct zfcp_erp_action {
struct zfcp_adapter {
u32 common_magic; /* driver common magic */
u32 specific_magic; /* struct specific magic */
struct list_head list; /* list of adapters */
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
......@@ -956,14 +949,12 @@ struct zfcp_adapter {
u32 hardware_version; /* of FCP channel */
u8 serial_number[32]; /* of hardware */
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
unsigned short scsi_host_no; /* Assigned host number */
unsigned char name[9];
struct list_head port_list_head; /* remote port list */
struct list_head port_remove_lh; /* head of ports to be
removed */
u32 ports; /* number of remote ports */
scsi_id_t max_scsi_id; /* largest SCSI ID */
scsi_lun_t max_scsi_lun; /* largest SCSI LUN */
struct timer_list scsi_er_timer; /* SCSI err recovery watch */
struct list_head fsf_req_list_head; /* head of FSF req list */
rwlock_t fsf_req_list_lock; /* lock for ops on list of
......@@ -1003,9 +994,13 @@ struct zfcp_adapter {
struct qdio_initialize qdio_init_data; /* for qdio_establish */
};
/*
* the struct device sysfs_device must be at the beginning of this structure.
* pointer to struct device is used to free port structure in release function
* of the device. don't change!
*/
struct zfcp_port {
u32 common_magic; /* driver wide common magic */
u32 specific_magic; /* structure specific magic */
struct device sysfs_device; /* sysfs device */
struct list_head list; /* list of remote ports */
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
......@@ -1020,37 +1015,36 @@ struct zfcp_port {
wwn_t wwnn; /* WWNN if known */
wwn_t wwpn; /* WWPN */
fc_id_t d_id; /* D_ID */
scsi_lun_t max_scsi_lun; /* largest SCSI LUN */
u32 handle; /* handle assigned by FSF */
struct zfcp_erp_action erp_action; /* pending error recovery */
atomic_t erp_counter;
struct device sysfs_device; /* sysfs device */
};
/* the struct device sysfs_device must be at the beginning of this structure.
* pointer to struct device is used to free unit structure in release function
* of the device. don't change!
*/
struct zfcp_unit {
u32 common_magic; /* driver wide common magic */
u32 specific_magic; /* structure specific magic */
struct device sysfs_device; /* sysfs device */
struct list_head list; /* list of logical units */
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
struct zfcp_port *port; /* remote port of unit */
atomic_t status; /* status of this logical unit */
u32 lun_access; /* access flags for this unit */
scsi_lun_t scsi_lun; /* own SCSI LUN */
fcp_lun_t fcp_lun; /* own FCP_LUN */
u32 handle; /* handle assigned by FSF */
struct scsi_device *device; /* scsi device struct pointer */
struct zfcp_erp_action erp_action; /* pending error recovery */
atomic_t erp_counter;
struct device sysfs_device; /* sysfs device */
atomic_t scsi_add_work; /* used to synchronize */
wait_queue_head_t scsi_add_wq; /* wait for scsi_add_device */
};
/* FSF request */
struct zfcp_fsf_req {
u32 common_magic; /* driver wide common magic */
u32 specific_magic; /* structure specific magic */
struct list_head list; /* list of FSF requests */
struct zfcp_adapter *adapter; /* adapter request belongs to */
u8 sbal_number; /* nr of SBALs free for use */
......@@ -1158,13 +1152,6 @@ struct zfcp_fsf_req_pool_element {
#define ZFCP_INTERRUPTIBLE 1
#define ZFCP_UNINTERRUPTIBLE 0
/* some magics which may be used to authenticate data structures */
#define ZFCP_MAGIC 0xFCFCFCFC
#define ZFCP_MAGIC_ADAPTER 0xAAAAAAAA
#define ZFCP_MAGIC_PORT 0xBBBBBBBB
#define ZFCP_MAGIC_UNIT 0xCCCCCCCC
#define ZFCP_MAGIC_FSFREQ 0xEEEEEEEE
#ifndef atomic_test_mask
#define atomic_test_mask(mask, target) \
((atomic_read(target) & mask) == mask)
......
......@@ -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.44 $"
#define ZFCP_ERP_REVISION "$Revision: 1.49 $"
#include "zfcp_ext.h"
......@@ -1202,7 +1202,7 @@ zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action,
* returns: 0 - there was an action to handle
* !0 - otherwise
*/
static int
int
zfcp_erp_async_handler(struct zfcp_erp_action *erp_action,
unsigned long set_mask)
{
......@@ -1217,28 +1217,6 @@ zfcp_erp_async_handler(struct zfcp_erp_action *erp_action,
return retval;
}
/*
* purpose: is called for finished FSF requests related to erp,
* moves concerned erp action to 'ready' queue and
* signals erp thread to process it,
* besides it cancels a timeout
*/
void
zfcp_erp_fsf_req_handler(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_erp_action *erp_action = fsf_req->erp_action;
struct zfcp_adapter *adapter = fsf_req->adapter;
debug_text_event(adapter->erp_dbf, 3, "a_frh");
debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
if (erp_action) {
debug_event(adapter->erp_dbf, 3, &erp_action->action,
sizeof (int));
zfcp_erp_async_handler(erp_action, 0);
}
}
/*
* purpose: is called for erp_action which was slept waiting for
* memory becoming avaliable,
......@@ -1892,7 +1870,7 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit)
unit->fcp_lun,
unit->port->wwpn,
zfcp_get_busid_by_unit(unit));
atomic_set(&p->unit->scsi_add_work, 0);
atomic_set(&unit->scsi_add_work, 0);
return -ENOMEM;
}
......@@ -2500,10 +2478,8 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
("bug: Could not clean QDIO (data transfer mechanism) "
"queues. (debug info %i).\n", retval_cleanup);
}
#ifdef ZFCP_DEBUG_REQUESTS
else
debug_text_event(adapter->req_dbf, 1, "q_clean");
#endif /* ZFCP_DEBUG_REQUESTS */
failed_qdio_establish:
atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
......@@ -2577,9 +2553,7 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
zfcp_get_busid_by_adapter(adapter));
} else {
ZFCP_LOG_DEBUG("queues cleaned up\n");
#ifdef ZFCP_DEBUG_REQUESTS
debug_text_event(adapter->req_dbf, 1, "q_clean");
#endif /* ZFCP_DEBUG_REQUESTS */
}
/*
......
......@@ -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.45 $"
#define ZFCP_EXT_REVISION "$Revision: 1.49 $"
#include "zfcp_def.h"
......@@ -55,7 +55,9 @@ extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *,
extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *,
wwn_t wwpn);
extern struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *);
extern int zfcp_adapter_debug_register(struct zfcp_adapter *);
extern void zfcp_adapter_dequeue(struct zfcp_adapter *);
extern void zfcp_adapter_debug_unregister(struct zfcp_adapter *);
extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t, u32);
extern void zfcp_port_dequeue(struct zfcp_port *);
extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t);
......@@ -158,7 +160,7 @@ extern void zfcp_erp_scsi_low_mem_buffer_timeout_handler(unsigned long);
extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
extern int zfcp_erp_thread_kill(struct zfcp_adapter *);
extern int zfcp_erp_wait(struct zfcp_adapter *);
extern void zfcp_erp_fsf_req_handler(struct zfcp_fsf_req *);
extern int zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long);
extern int zfcp_test_link(struct zfcp_port *);
......
This diff is collapsed.
......@@ -108,6 +108,7 @@
#define FSF_CONFLICTS_OVERRULED 0x00000058
#define FSF_PORT_BOXED 0x00000059
#define FSF_LUN_BOXED 0x0000005A
#define FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE 0x0000005B
#define FSF_PAYLOAD_SIZE_MISMATCH 0x00000060
#define FSF_REQUEST_SIZE_TOO_LARGE 0x00000061
#define FSF_RESPONSE_SIZE_TOO_LARGE 0x00000062
......@@ -156,7 +157,6 @@
#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004
#define FSF_STATUS_READ_LINK_DOWN 0x00000005 /* FIXME: really? */
#define FSF_STATUS_READ_LINK_UP 0x00000006
#define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009
#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A
#define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B
......@@ -165,8 +165,6 @@
#define FSF_STATUS_READ_SUB_ERROR_PORT 0x00000002
/* status subtypes for CFDC */
#define FSF_STATUS_READ_SUB_LOST_CFDC_UPDATED 0x00000020
#define FSF_STATUS_READ_SUB_LOST_CFDC_HARDENED 0x00000040
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F
......@@ -198,18 +196,23 @@
/* channel features */
#define FSF_FEATURE_QTCB_SUPPRESSION 0x00000001
#define FSF_FEATURE_CFDC 0x00000002
#define FSF_FEATURE_SENSEDATA_REPLICATION 0x00000004
#define FSF_FEATURE_LOST_SAN_NOTIFICATION 0x00000008
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
/* option */
#define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001
#define FSF_OPEN_LUN_UNSOLICITED_SENSE_DATA 0x00000002
/* adapter types */
#define FSF_ADAPTER_TYPE_FICON 0x00000001
#define FSF_ADAPTER_TYPE_FICON_EXPRESS 0x00000002
/* flags */
#define FSF_CFDC_OPEN_LUN_ALLOWED 0x01
#define FSF_CFDC_EXCLUSIVE_ACCESS 0x02
#define FSF_CFDC_OUTBOUND_TRANSFER_ALLOWED 0x10
/* port types */
#define FSF_HBA_PORTTYPE_UNKNOWN 0x00000001
#define FSF_HBA_PORTTYPE_NOTPRESENT 0x00000003
......@@ -394,9 +397,10 @@ struct fsf_qtcb_bottom_support {
u64 res2;
u64 req_handle;
u32 service_class;
u8 res3[3];
u8 res3[3];
u8 timeout;
u8 res4[184];
u32 lun_access;
u8 res4[180];
u32 els1_length;
u32 els2_length;
u32 req_buf_length;
......
......@@ -28,7 +28,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_QDIO_C_REVISION "$Revision: 1.13 $"
#define ZFCP_QDIO_C_REVISION "$Revision: 1.16 $"
#include "zfcp_ext.h"
......@@ -485,11 +485,9 @@ zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
struct zfcp_fsf_req *fsf_req;
int retval = 0;
#ifdef ZFCP_DEBUG_REQUESTS
/* Note: seq is entered later */
debug_text_event(adapter->req_dbf, 1, "i:a/seq");
debug_event(adapter->req_dbf, 1, &sbale_addr, sizeof (unsigned long));
#endif /* ZFCP_DEBUG_REQUESTS */
/* invalid (per convention used in this driver) */
if (unlikely(!sbale_addr)) {
......@@ -502,17 +500,6 @@ zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
/* valid request id and thus (hopefully :) valid fsf_req address */
fsf_req = (struct zfcp_fsf_req *) sbale_addr;
if (unlikely((fsf_req->common_magic != ZFCP_MAGIC) ||
(fsf_req->specific_magic != ZFCP_MAGIC_FSFREQ))) {
ZFCP_LOG_NORMAL("bug: An inbound FSF acknowledgement was "
"faulty (debug info 0x%x, 0x%x, 0x%lx)\n",
fsf_req->common_magic,
fsf_req->specific_magic,
(unsigned long) fsf_req);
retval = -EINVAL;
goto out;
}
if (unlikely(adapter != fsf_req->adapter)) {
ZFCP_LOG_NORMAL("bug: An inbound FSF acknowledgement was not "
"correct (debug info 0x%lx, 0x%lx, 0%lx) \n",
......@@ -522,13 +509,11 @@ zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
retval = -EINVAL;
goto out;
}
#ifdef ZFCP_DEBUG_REQUESTS
/* debug feature stuff (test for QTCB: remember new unsol. status!) */
if (likely(fsf_req->qtcb)) {
debug_event(adapter->req_dbf, 1,
&fsf_req->qtcb->prefix.req_seq_no, sizeof (u32));
}
#endif /* ZFCP_DEBUG_REQUESTS */
ZFCP_LOG_TRACE("fsf_req at 0x%lx, QTCB at 0x%lx\n",
(unsigned long) fsf_req, (unsigned long) fsf_req->qtcb);
......
......@@ -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.52 $"
#define ZFCP_SCSI_REVISION "$Revision: 1.59 $"
#include <linux/blkdev.h>
......@@ -48,14 +48,15 @@ static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *);
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
static int zfcp_task_management_function(struct zfcp_unit *, u8);
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, int, int);
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,
scsi_lun_t);
static struct device_attribute *zfcp_sysfs_sdev_attrs[];
struct zfcp_data zfcp_data = {
.scsi_host_template = {
name: ZFCP_NAME,
proc_name: "dummy",
proc_name: "zfcp",
proc_info: NULL,
detect: NULL,
slave_alloc: zfcp_scsi_slave_alloc,
......@@ -299,12 +300,9 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit,
ZFCP_LOG_DEBUG("error: Could not send a Send FCP Command\n");
retval = SCSI_MLQUEUE_HOST_BUSY;
} else {
#ifdef ZFCP_DEBUG_REQUESTS
debug_text_event(adapter->req_dbf, 3, "q_scpnt");
debug_event(adapter->req_dbf, 3, &scpnt,
sizeof (unsigned long));
#endif /* ZFCP_DEBUG_REQUESTS */
}
out:
......@@ -376,7 +374,8 @@ zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
* context:
*/
static struct zfcp_unit *
zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, int id, int lun)
zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id,
scsi_lun_t lun)
{
struct zfcp_port *port;
struct zfcp_unit *unit, *retval = NULL;
......@@ -426,8 +425,6 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
unsigned long flags;
u32 status = 0;
#ifdef ZFCP_DEBUG_ABORTS
/* the components of a abort_dbf record (fixed size record) */
u64 dbf_scsi_cmnd = (unsigned long) scpnt;
char dbf_opcode[ZFCP_ABORT_DBF_LENGTH];
......@@ -445,7 +442,6 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
memcpy(dbf_opcode,
scpnt->cmnd,
min(scpnt->cmd_len, (unsigned char) ZFCP_ABORT_DBF_LENGTH));
#endif
/*TRACE*/
ZFCP_LOG_INFO
......@@ -488,11 +484,11 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
/* Figure out which fsf_req needs to be aborted. */
old_fsf_req = req_data->send_fcp_command_task.fsf_req;
#ifdef ZFCP_DEBUG_ABORTS
dbf_fsf_req = (unsigned long) old_fsf_req;
dbf_timeout =
(jiffies - req_data->send_fcp_command_task.start_jiffies) / HZ;
#endif
/* DEBUG */
ZFCP_LOG_DEBUG("old_fsf_req=0x%lx\n", (unsigned long) old_fsf_req);
if (!old_fsf_req) {
......@@ -548,7 +544,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
/* wait for completion of abort */
ZFCP_LOG_DEBUG("Waiting for cleanup....\n");
#ifdef ZFCP_DEBUG_ABORTS
#ifdef 1
/*
* FIXME:
* copying zfcp_fsf_req_wait_and_cleanup code is not really nice
......@@ -584,8 +580,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
strncpy(dbf_result, "##fail", ZFCP_ABORT_DBF_LENGTH);
}
out:
#ifdef ZFCP_DEBUG_ABORTS
out:
debug_event(adapter->abort_dbf, 1, &dbf_scsi_cmnd, sizeof (u64));
debug_event(adapter->abort_dbf, 1, &dbf_opcode, ZFCP_ABORT_DBF_LENGTH);
debug_event(adapter->abort_dbf, 1, &dbf_wwn, sizeof (wwn_t));
......@@ -598,7 +593,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[0], sizeof (u64));
debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[1], sizeof (u64));
debug_text_event(adapter->abort_dbf, 1, dbf_result);
#endif
spin_lock_irq(scsi_host->host_lock);
return retval;
}
......@@ -796,11 +791,16 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
(unsigned long) adapter->scsi_host);
/* tell the SCSI stack some characteristics of this adapter */
adapter->scsi_host->max_id = adapter->max_scsi_id + 1;
adapter->scsi_host->max_lun = adapter->max_scsi_lun + 1;
adapter->scsi_host->max_id = 1;
adapter->scsi_host->max_lun = 1;
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;
/*
* Reverse mapping of the host number to avoid race condition
*/
adapter->scsi_host_no = adapter->scsi_host->host_no;
/*
* save a pointer to our own adapter data structure within
* hostdata field of SCSI host data structure
......@@ -835,6 +835,7 @@ zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
scsi_remove_host(shost);
scsi_host_put(shost);
adapter->scsi_host = NULL;
adapter->scsi_host_no = 0;
atomic_clear_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status);
return;
......@@ -850,68 +851,32 @@ zfcp_fsf_start_scsi_er_timer(struct zfcp_adapter *adapter)
add_timer(&adapter->scsi_er_timer);
}
/**
* zfcp_sysfs_hba_id_show - display hba_id of scsi device
* @dev: pointer to belonging device
* @buf: pointer to input buffer
*
* "hba_id" attribute of a scsi device. Displays hba_id (bus_id)
* of the adapter belonging to a scsi device.
*/
static ssize_t
zfcp_sysfs_hba_id_show(struct device *dev, char *buf)
{
struct scsi_device *sdev;
struct zfcp_unit *unit;
sdev = to_scsi_device(dev);
unit = (struct zfcp_unit *) sdev->hostdata;
return sprintf(buf, "%s\n", zfcp_get_busid_by_unit(unit));
}
static DEVICE_ATTR(hba_id, S_IRUGO, zfcp_sysfs_hba_id_show, NULL);
/**
* zfcp_sysfs_wwpn_show - display wwpn of scsi device
* @dev: pointer to belonging device
* @buf: pointer to input buffer
* ZFCP_DEFINE_SCSI_ATTR
* @_name: name of show attribute
* @_format: format string
* @_value: value to print
*
* "wwpn" attribute of a scsi device. Displays wwpn of the port
* belonging to a scsi device.
* Generates attribute for a unit.
*/
static ssize_t
zfcp_sysfs_wwpn_show(struct device *dev, char *buf)
{
struct scsi_device *sdev;
struct zfcp_unit *unit;
sdev = to_scsi_device(dev);
unit = (struct zfcp_unit *) sdev->hostdata;
return sprintf(buf, "0x%016llx\n", unit->port->wwpn);
}
static DEVICE_ATTR(wwpn, S_IRUGO, zfcp_sysfs_wwpn_show, NULL);
/**
* zfcp_sysfs_fcp_lun_show - display fcp lun of scsi device
* @dev: pointer to belonging device
* @buf: pointer to input buffer
*
* "fcp_lun" attribute of a scsi device. Displays fcp_lun of the unit
* belonging to a scsi device.
*/
static ssize_t
zfcp_sysfs_fcp_lun_show(struct device *dev, char *buf)
{
struct scsi_device *sdev;
struct zfcp_unit *unit;
sdev = to_scsi_device(dev);
unit = (struct zfcp_unit *) sdev->hostdata;
return sprintf(buf, "0x%016llx\n", unit->fcp_lun);
}
static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_fcp_lun_show, NULL);
#define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value) \
static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \
char *buf) \
{ \
struct scsi_device *sdev; \
struct zfcp_unit *unit; \
\
sdev = to_scsi_device(dev); \
unit = sdev->hostdata; \
return sprintf(buf, _format, _value); \
} \
\
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);
ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", zfcp_get_busid_by_unit(unit));
ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", unit->port->wwpn);
ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", unit->fcp_lun);
static struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
&dev_attr_fcp_lun,
......
......@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_SYSFS_ADAPTER_C_REVISION "$Revision: 1.30 $"
#define ZFCP_SYSFS_ADAPTER_C_REVISION "$Revision: 1.32 $"
#include <asm/ccwdev.h>
#include "zfcp_ext.h"
......@@ -75,6 +75,7 @@ ZFCP_DEFINE_ADAPTER_ATTR(fc_topology, "%s\n",
ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n",
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
......@@ -99,30 +100,6 @@ zfcp_sysfs_adapter_in_recovery_show(struct device *dev, char *buf)
static DEVICE_ATTR(in_recovery, S_IRUGO,
zfcp_sysfs_adapter_in_recovery_show, NULL);
/**
* zfcp_sysfs_adapter_scsi_host_no_show - display scsi_host_no of adapter
* @dev: pointer to belonging device
* @buf: pointer to input buffer
*
* "scsi_host_no" attribute of adapter. Displays the SCSI host number.
*/
static ssize_t
zfcp_sysfs_adapter_scsi_host_no_show(struct device *dev, char *buf)
{
struct zfcp_adapter *adapter;
unsigned short host_no = 0;
down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(dev);
if (adapter->scsi_host)
host_no = adapter->scsi_host->host_no;
up(&zfcp_data.config_sema);
return sprintf(buf, "0x%x\n", host_no);
}
static DEVICE_ATTR(scsi_host_no, S_IRUGO, zfcp_sysfs_adapter_scsi_host_no_show,
NULL);
/**
* zfcp_sysfs_port_add_store - add a port to sysfs tree
* @dev: pointer to belonging device
......@@ -219,9 +196,7 @@ zfcp_sysfs_port_remove_store(struct device *dev, const char *buf, size_t count)
zfcp_erp_port_shutdown(port, 0);
zfcp_erp_wait(adapter);
zfcp_port_put(port);
zfcp_sysfs_port_remove_files(&port->sysfs_device,
atomic_read(&port->status));
device_unregister(&port->sysfs_device);
zfcp_port_dequeue(port);
out:
up(&zfcp_data.config_sema);
return retval ? retval : count;
......
......@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_SYSFS_PORT_C_REVISION "$Revision: 1.37 $"
#define ZFCP_SYSFS_PORT_C_REVISION "$Revision: 1.39 $"
#include <linux/init.h>
#include <linux/module.h>
......@@ -43,11 +43,7 @@
void
zfcp_sysfs_port_release(struct device *dev)
{
struct zfcp_port *port;
port = dev_get_drvdata(dev);
zfcp_port_dequeue(port);
return;
kfree(dev);
}
/**
......@@ -112,7 +108,6 @@ zfcp_sysfs_unit_add_store(struct device *dev, const char *buf, size_t count)
zfcp_erp_unit_reopen(unit, 0);
zfcp_erp_wait(unit->port->adapter);
wait_event(unit->scsi_add_wq, atomic_read(&unit->scsi_add_work) == 0);
zfcp_unit_put(unit);
out:
up(&zfcp_data.config_sema);
......@@ -168,8 +163,7 @@ zfcp_sysfs_unit_remove_store(struct device *dev, const char *buf, size_t count)
zfcp_erp_unit_shutdown(unit, 0);
zfcp_erp_wait(unit->port->adapter);
zfcp_unit_put(unit);
zfcp_sysfs_unit_remove_files(&unit->sysfs_device);
device_unregister(&unit->sysfs_device);
zfcp_unit_dequeue(unit);
out:
up(&zfcp_data.config_sema);
return retval ? retval : count;
......
......@@ -26,7 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define ZFCP_SYSFS_UNIT_C_REVISION "$Revision: 1.23 $"
#define ZFCP_SYSFS_UNIT_C_REVISION "$Revision: 1.24 $"
#include <linux/init.h>
#include <linux/module.h>
......@@ -43,11 +43,7 @@
void
zfcp_sysfs_unit_release(struct device *dev)
{
struct zfcp_unit *unit;
unit = dev_get_drvdata(dev);
zfcp_unit_dequeue(unit);
return;
kfree(dev);
}
/**
......
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