X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fscsi%2Fzfcp_scsi.c;h=e21b547fd427836cc49bad40393c5643f184c5ba;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=6c08081638195e89cb14b50b0b07760723b5c979;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 6c0808163..e21b547fd 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -12,6 +12,7 @@ * Wolfgang Taphorn * Stefan Bader * Heiko Carstens + * Andreas Herrmann * * 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, }; /**