vserver 1.9.5.x5
[linux-2.6.git] / drivers / s390 / scsi / zfcp_scsi.c
index 6c08081..e21b547 100644 (file)
@@ -12,6 +12,7 @@
  *            Wolfgang Taphorn
  *            Stefan Bader <stefan.bader@de.ibm.com> 
  *            Heiko Carstens <heiko.carstens@de.ibm.com> 
+ *            Andreas Herrmann <aherrman@de.ibm.com>
  * 
  * This program is free software; you can redistribute it and/or modify 
  * it under the terms of the GNU General Public License as published by 
@@ -30,8 +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.68 $"
+#define ZFCP_SCSI_REVISION "$Revision: 1.74 $"
 
 #include "zfcp_ext.h"
 
@@ -48,6 +48,8 @@ static int zfcp_task_management_function(struct zfcp_unit *, u8);
 
 static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,
                                          scsi_lun_t);
+static struct zfcp_port *zfcp_port_lookup(struct zfcp_adapter *, int,
+                                         scsi_id_t);
 
 static struct device_attribute *zfcp_sysfs_sdev_attrs[];
 
@@ -79,7 +81,8 @@ struct zfcp_data zfcp_data = {
              unchecked_isa_dma:       0,
              use_clustering:          1,
              sdev_attrs:              zfcp_sysfs_sdev_attrs,
-       }
+       },
+       .driver_version = ZFCP_VERSION,
        /* rest initialised with zeros */
 };
 
@@ -331,8 +334,8 @@ zfcp_scsi_command_sync(struct zfcp_unit *unit, struct scsi_cmnd *scpnt,
        scpnt->SCp.ptr = (void *) &wait;  /* silent re-use */
        scpnt->scsi_done = zfcp_scsi_command_sync_handler;
        ret = zfcp_scsi_command_async(unit->port->adapter, unit, scpnt, timer);
-       if ((ret == 0) && (scpnt->result == 0))
-       wait_for_completion(&wait);
+       if (ret == 0)
+               wait_for_completion(&wait);
 
        scpnt->SCp.ptr = NULL;
 
@@ -399,6 +402,18 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id,
        return retval;
 }
 
+static struct zfcp_port *
+zfcp_port_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id)
+{
+       struct zfcp_port *port;
+
+       list_for_each_entry(port, &adapter->port_list_head, list) {
+               if (id == port->scsi_id)
+                       return port;
+       }
+       return (struct zfcp_port *) NULL;
+}
+
 /*
  * function:   zfcp_scsi_eh_abort_handler
  *
@@ -629,7 +644,7 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
        if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
                              &unit->status)) {
                retval =
-                   zfcp_task_management_function(unit, LOGICAL_UNIT_RESET);
+                   zfcp_task_management_function(unit, FCP_LOGICAL_UNIT_RESET);
                if (retval) {
                        ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);
                        if (retval == -ENOTSUPP)
@@ -645,7 +660,7 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
                        goto out;
                }
        }
-       retval = zfcp_task_management_function(unit, TARGET_RESET);
+       retval = zfcp_task_management_function(unit, FCP_TARGET_RESET);
        if (retval) {
                ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);
                retval = FAILED;
@@ -839,39 +854,63 @@ zfcp_fsf_start_scsi_er_timer(struct zfcp_adapter *adapter)
  * Support functions for FC transport class
  */
 static void
-zfcp_get_port_id(struct scsi_device *sdev)
+zfcp_get_port_id(struct scsi_target *starget)
 {
-       struct zfcp_unit *unit;
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0];
+       struct zfcp_port *port;
+       unsigned long flags;
 
-       unit = (struct zfcp_unit *) sdev->hostdata;
-       fc_port_id(sdev) = unit->port->d_id;
+       read_lock_irqsave(&zfcp_data.config_lock, flags);
+       port = zfcp_port_lookup(adapter, starget->channel, starget->id);
+       if (port)
+               fc_starget_port_id(starget) = port->d_id;
+       else
+               fc_starget_port_id(starget) = -1;
+       read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
 static void
-zfcp_get_port_name(struct scsi_device *sdev)
+zfcp_get_port_name(struct scsi_target *starget)
 {
-       struct zfcp_unit *unit;
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0];
+       struct zfcp_port *port;
+       unsigned long flags;
 
-       unit = (struct zfcp_unit *) sdev->hostdata;
-       fc_port_name(sdev) = unit->port->wwpn;
+       read_lock_irqsave(&zfcp_data.config_lock, flags);
+       port = zfcp_port_lookup(adapter, starget->channel, starget->id);
+       if (port)
+               fc_starget_port_name(starget) = port->wwpn;
+       else
+               fc_starget_port_name(starget) = -1;
+       read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
 static void
-zfcp_get_node_name(struct scsi_device *sdev)
+zfcp_get_node_name(struct scsi_target *starget)
 {
-       struct zfcp_unit *unit;
+       struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+       struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0];
+       struct zfcp_port *port;
+       unsigned long flags;
 
-       unit = (struct zfcp_unit *) sdev->hostdata;
-       fc_node_name(sdev) = unit->port->wwnn;
+       read_lock_irqsave(&zfcp_data.config_lock, flags);
+       port = zfcp_port_lookup(adapter, starget->channel, starget->id);
+       if (port)
+               fc_starget_node_name(starget) = port->wwnn;
+       else
+               fc_starget_node_name(starget) = -1;
+       read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
 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,
+       .get_starget_port_id = zfcp_get_port_id,
+       .get_starget_port_name = zfcp_get_port_name,
+       .get_starget_node_name = zfcp_get_node_name,
+       .show_starget_port_id = 1,
+       .show_starget_port_name = 1,
+       .show_starget_node_name = 1,
 };
 
 /**