#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.68 $"
#include "zfcp_ext.h"
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,
/**
* zfcp_scsi_command_async - worker for zfcp_scsi_queuecommand and
* zfcp_scsi_command_sync
- * @adapter: adapter for where scsi command is issued
+ * @adapter: adapter where scsi command is issued
* @unit: unit to which scsi command is sent
* @scpnt: scsi command to be sent
+ * @timer: timer to be started if request is successfully initiated
*
* Note: In scsi_done function must be set in scpnt.
*/
int
zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit,
- struct scsi_cmnd *scpnt)
+ struct scsi_cmnd *scpnt, struct timer_list *timer)
{
int tmp;
int retval;
goto out;
}
- tmp = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt,
+ tmp = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, timer,
ZFCP_REQ_AUTO_CLEANUP);
if (unlikely(tmp < 0)) {
/**
* zfcp_scsi_command_sync - send a SCSI command and wait for completion
- * returns 0, errors are indicated by scsi_cmnd->result
+ * @unit: unit where command is sent to
+ * @scpnt: scsi command to be sent
+ * @timer: timer to be started if request is successfully initiated
+ * Return: 0
+ *
+ * Errors are indicated in scpnt->result
*/
int
-zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt)
+zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt,
+ struct timer_list *timer)
{
+ int ret;
DECLARE_COMPLETION(wait);
scpnt->SCp.ptr = (void *) &wait; /* silent re-use */
- scpnt->done = zfcp_scsi_command_sync_handler;
- zfcp_scsi_command_async(unit->port->adapter, unit, scpnt);
+ scpnt->scsi_done = zfcp_scsi_command_sync_handler;
+ ret = zfcp_scsi_command_async(unit->port->adapter, unit, scpnt, timer);
+ if ((ret == 0) && (scpnt->result == 0))
wait_for_completion(&wait);
+ scpnt->SCp.ptr = NULL;
+
return 0;
}
adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0];
unit = (struct zfcp_unit *) scpnt->device->hostdata;
- return zfcp_scsi_command_async(adapter, unit, scpnt);
+ return zfcp_scsi_command_async(adapter, unit, scpnt, NULL);
}
/*
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,
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
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;
/* 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 "
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
*/
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