Skip to content

Commit 3859f6a

Browse files
Andreas HerrmannLinus Torvalds
Andreas Herrmann
authored and
Linus Torvalds
committed
[PATCH] zfcp: add rports to enable scsi_add_device to work again
This patch fixes a severe problem with 2.6.13-rc7. Due to recent SCSI changes it is not possible to add any LUNs to the zfcp device driver anymore. With registration of remote ports this is fixed. Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com> Acked-by: James Bottomley <jejb@steeleye.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent 729d70f commit 3859f6a

File tree

7 files changed

+63
-31
lines changed

7 files changed

+63
-31
lines changed

drivers/s390/scsi/zfcp_aux.c

+7-22
Original file line numberDiff line numberDiff line change
@@ -1299,13 +1299,10 @@ struct zfcp_port *
12991299
zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
13001300
u32 d_id)
13011301
{
1302-
struct zfcp_port *port, *tmp_port;
1302+
struct zfcp_port *port;
13031303
int check_wwpn;
1304-
scsi_id_t scsi_id;
1305-
int found;
13061304

13071305
check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN);
1308-
13091306
/*
13101307
* check that there is no port with this WWPN already in list
13111308
*/
@@ -1368,7 +1365,7 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
13681365
} else {
13691366
snprintf(port->sysfs_device.bus_id,
13701367
BUS_ID_SIZE, "0x%016llx", wwpn);
1371-
port->sysfs_device.parent = &adapter->ccw_device->dev;
1368+
port->sysfs_device.parent = &adapter->ccw_device->dev;
13721369
}
13731370
port->sysfs_device.release = zfcp_sysfs_port_release;
13741371
dev_set_drvdata(&port->sysfs_device, port);
@@ -1388,24 +1385,8 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
13881385

13891386
zfcp_port_get(port);
13901387

1391-
scsi_id = 1;
1392-
found = 0;
13931388
write_lock_irq(&zfcp_data.config_lock);
1394-
list_for_each_entry(tmp_port, &adapter->port_list_head, list) {
1395-
if (atomic_test_mask(ZFCP_STATUS_PORT_NO_SCSI_ID,
1396-
&tmp_port->status))
1397-
continue;
1398-
if (tmp_port->scsi_id != scsi_id) {
1399-
found = 1;
1400-
break;
1401-
}
1402-
scsi_id++;
1403-
}
1404-
port->scsi_id = scsi_id;
1405-
if (found)
1406-
list_add_tail(&port->list, &tmp_port->list);
1407-
else
1408-
list_add_tail(&port->list, &adapter->port_list_head);
1389+
list_add_tail(&port->list, &adapter->port_list_head);
14091390
atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
14101391
atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
14111392
if (d_id == ZFCP_DID_DIRECTORY_SERVICE)
@@ -1422,11 +1403,15 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
14221403
void
14231404
zfcp_port_dequeue(struct zfcp_port *port)
14241405
{
1406+
struct fc_port *rport;
1407+
14251408
zfcp_port_wait(port);
14261409
write_lock_irq(&zfcp_data.config_lock);
14271410
list_del(&port->list);
14281411
port->adapter->ports--;
14291412
write_unlock_irq(&zfcp_data.config_lock);
1413+
if (port->rport)
1414+
fc_remote_port_delete(rport);
14301415
zfcp_adapter_put(port->adapter);
14311416
zfcp_sysfs_port_remove_files(&port->sysfs_device,
14321417
atomic_read(&port->status));

drivers/s390/scsi/zfcp_ccw.c

+10
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,19 @@ static int
202202
zfcp_ccw_set_offline(struct ccw_device *ccw_device)
203203
{
204204
struct zfcp_adapter *adapter;
205+
struct zfcp_port *port;
206+
struct fc_port *rport;
205207

206208
down(&zfcp_data.config_sema);
207209
adapter = dev_get_drvdata(&ccw_device->dev);
210+
/* might be racy, but we cannot take config_lock due to the fact that
211+
fc_remote_port_delete might sleep */
212+
list_for_each_entry(port, &adapter->port_list_head, list)
213+
if (port->rport) {
214+
rport = port->rport;
215+
port->rport = NULL;
216+
fc_remote_port_delete(rport);
217+
}
208218
zfcp_erp_adapter_shutdown(adapter, 0);
209219
zfcp_erp_wait(adapter);
210220
zfcp_adapter_scsi_unregister(adapter);

drivers/s390/scsi/zfcp_def.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,7 @@ struct zfcp_adapter {
906906
*/
907907
struct zfcp_port {
908908
struct device sysfs_device; /* sysfs device */
909+
struct fc_rport *rport; /* rport of fc transport class */
909910
struct list_head list; /* list of remote ports */
910911
atomic_t refcount; /* reference count */
911912
wait_queue_head_t remove_wq; /* can be used to wait for
@@ -916,7 +917,6 @@ struct zfcp_port {
916917
list */
917918
u32 units; /* # of logical units in list */
918919
atomic_t status; /* status of this remote port */
919-
scsi_id_t scsi_id; /* own SCSI ID */
920920
wwn_t wwnn; /* WWNN if known */
921921
wwn_t wwpn; /* WWPN */
922922
fc_id_t d_id; /* D_ID */

drivers/s390/scsi/zfcp_erp.c

+22-3
Original file line numberDiff line numberDiff line change
@@ -3360,13 +3360,32 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
33603360
if ((result == ZFCP_ERP_SUCCEEDED)
33613361
&& (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY,
33623362
&unit->status))
3363-
&& (!unit->device))
3364-
scsi_add_device(unit->port->adapter->scsi_host, 0,
3365-
unit->port->scsi_id, unit->scsi_lun);
3363+
&& !unit->device
3364+
&& port->rport)
3365+
scsi_add_device(port->adapter->scsi_host, 0,
3366+
port->rport->scsi_target_id,
3367+
unit->scsi_lun);
33663368
zfcp_unit_put(unit);
33673369
break;
33683370
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
33693371
case ZFCP_ERP_ACTION_REOPEN_PORT:
3372+
if ((result == ZFCP_ERP_SUCCEEDED)
3373+
&& !atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN,
3374+
&port->status)
3375+
&& !port->rport) {
3376+
struct fc_rport_identifiers ids;
3377+
ids.node_name = port->wwnn;
3378+
ids.port_name = port->wwpn;
3379+
ids.port_id = port->d_id;
3380+
ids.roles = FC_RPORT_ROLE_FCP_TARGET;
3381+
port->rport =
3382+
fc_remote_port_add(adapter->scsi_host, 0, &ids);
3383+
if (!port->rport)
3384+
ZFCP_LOG_NORMAL("failed registration of rport"
3385+
"(adapter %s, wwpn=0x%016Lx)\n",
3386+
zfcp_get_busid_by_port(port),
3387+
port->wwpn);
3388+
}
33703389
zfcp_port_put(port);
33713390
break;
33723391
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:

drivers/s390/scsi/zfcp_ext.h

+2
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *,
143143
struct scsi_cmnd *, struct timer_list *);
144144
extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *,
145145
struct timer_list *);
146+
extern void zfcp_set_fc_host_attrs(struct zfcp_adapter *);
147+
extern void zfcp_set_fc_rport_attrs(struct zfcp_port *);
146148
extern struct scsi_transport_template *zfcp_transport_template;
147149
extern struct fc_function_template zfcp_transport_functions;
148150

drivers/s390/scsi/zfcp_fsf.c

+1
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
20622062
zfcp_erp_adapter_shutdown(adapter, 0);
20632063
return -EIO;
20642064
}
2065+
zfcp_set_fc_host_attrs(adapter);
20652066
return 0;
20662067
}
20672068

drivers/s390/scsi/zfcp_scsi.c

+20-5
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id,
389389
struct zfcp_unit *unit, *retval = NULL;
390390

391391
list_for_each_entry(port, &adapter->port_list_head, list) {
392-
if (id != port->scsi_id)
392+
if (!port->rport || (id != port->rport->scsi_target_id))
393393
continue;
394394
list_for_each_entry(unit, &port->unit_list_head, list) {
395395
if (lun == unit->scsi_lun) {
@@ -408,7 +408,7 @@ zfcp_port_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id)
408408
struct zfcp_port *port;
409409

410410
list_for_each_entry(port, &adapter->port_list_head, list) {
411-
if (id == port->scsi_id)
411+
if (port->rport && (id == port->rport->scsi_target_id))
412412
return port;
413413
}
414414
return (struct zfcp_port *) NULL;
@@ -634,7 +634,6 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
634634
{
635635
int retval;
636636
struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
637-
struct Scsi_Host *scsi_host = scpnt->device->host;
638637

639638
if (!unit) {
640639
ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n");
@@ -729,7 +728,6 @@ zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
729728
{
730729
int retval = 0;
731730
struct zfcp_unit *unit;
732-
struct Scsi_Host *scsi_host = scpnt->device->host;
733731

734732
unit = (struct zfcp_unit *) scpnt->device->hostdata;
735733
ZFCP_LOG_NORMAL("bus reset because of problems with "
@@ -753,7 +751,6 @@ zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
753751
{
754752
int retval = 0;
755753
struct zfcp_unit *unit;
756-
struct Scsi_Host *scsi_host = scpnt->device->host;
757754

758755
unit = (struct zfcp_unit *) scpnt->device->hostdata;
759756
ZFCP_LOG_NORMAL("host reset because of problems with "
@@ -833,6 +830,7 @@ zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
833830
shost = adapter->scsi_host;
834831
if (!shost)
835832
return;
833+
fc_remove_host(shost);
836834
scsi_remove_host(shost);
837835
scsi_host_put(shost);
838836
adapter->scsi_host = NULL;
@@ -906,13 +904,30 @@ zfcp_get_node_name(struct scsi_target *starget)
906904
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
907905
}
908906

907+
void
908+
zfcp_set_fc_host_attrs(struct zfcp_adapter *adapter)
909+
{
910+
struct Scsi_Host *shost = adapter->scsi_host;
911+
912+
fc_host_node_name(shost) = adapter->wwnn;
913+
fc_host_port_name(shost) = adapter->wwpn;
914+
strncpy(fc_host_serial_number(shost), adapter->serial_number,
915+
min(FC_SERIAL_NUMBER_SIZE, 32));
916+
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
917+
}
918+
909919
struct fc_function_template zfcp_transport_functions = {
910920
.get_starget_port_id = zfcp_get_port_id,
911921
.get_starget_port_name = zfcp_get_port_name,
912922
.get_starget_node_name = zfcp_get_node_name,
913923
.show_starget_port_id = 1,
914924
.show_starget_port_name = 1,
915925
.show_starget_node_name = 1,
926+
.show_rport_supported_classes = 1,
927+
.show_host_node_name = 1,
928+
.show_host_port_name = 1,
929+
.show_host_supported_classes = 1,
930+
.show_host_serial_number = 1,
916931
};
917932

918933
/**

0 commit comments

Comments
 (0)