Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[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>

authored by

Andreas Herrmann and committed by
Linus Torvalds
3859f6a2 729d70f5

+63 -31
+7 -22
drivers/s390/scsi/zfcp_aux.c
··· 1299 1299 zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, 1300 1300 u32 d_id) 1301 1301 { 1302 - struct zfcp_port *port, *tmp_port; 1302 + struct zfcp_port *port; 1303 1303 int check_wwpn; 1304 - scsi_id_t scsi_id; 1305 - int found; 1306 1304 1307 1305 check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN); 1308 - 1309 1306 /* 1310 1307 * check that there is no port with this WWPN already in list 1311 1308 */ ··· 1365 1368 } else { 1366 1369 snprintf(port->sysfs_device.bus_id, 1367 1370 BUS_ID_SIZE, "0x%016llx", wwpn); 1368 - port->sysfs_device.parent = &adapter->ccw_device->dev; 1371 + port->sysfs_device.parent = &adapter->ccw_device->dev; 1369 1372 } 1370 1373 port->sysfs_device.release = zfcp_sysfs_port_release; 1371 1374 dev_set_drvdata(&port->sysfs_device, port); ··· 1385 1388 1386 1389 zfcp_port_get(port); 1387 1390 1388 - scsi_id = 1; 1389 - found = 0; 1390 1391 write_lock_irq(&zfcp_data.config_lock); 1391 - list_for_each_entry(tmp_port, &adapter->port_list_head, list) { 1392 - if (atomic_test_mask(ZFCP_STATUS_PORT_NO_SCSI_ID, 1393 - &tmp_port->status)) 1394 - continue; 1395 - if (tmp_port->scsi_id != scsi_id) { 1396 - found = 1; 1397 - break; 1398 - } 1399 - scsi_id++; 1400 - } 1401 - port->scsi_id = scsi_id; 1402 - if (found) 1403 - list_add_tail(&port->list, &tmp_port->list); 1404 - else 1405 - list_add_tail(&port->list, &adapter->port_list_head); 1392 + list_add_tail(&port->list, &adapter->port_list_head); 1406 1393 atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); 1407 1394 atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); 1408 1395 if (d_id == ZFCP_DID_DIRECTORY_SERVICE) ··· 1403 1422 void 1404 1423 zfcp_port_dequeue(struct zfcp_port *port) 1405 1424 { 1425 + struct fc_port *rport; 1426 + 1406 1427 zfcp_port_wait(port); 1407 1428 write_lock_irq(&zfcp_data.config_lock); 1408 1429 list_del(&port->list); 1409 1430 port->adapter->ports--; 1410 1431 write_unlock_irq(&zfcp_data.config_lock); 1432 + if (port->rport) 1433 + fc_remote_port_delete(rport); 1411 1434 zfcp_adapter_put(port->adapter); 1412 1435 zfcp_sysfs_port_remove_files(&port->sysfs_device, 1413 1436 atomic_read(&port->status));
+10
drivers/s390/scsi/zfcp_ccw.c
··· 202 202 zfcp_ccw_set_offline(struct ccw_device *ccw_device) 203 203 { 204 204 struct zfcp_adapter *adapter; 205 + struct zfcp_port *port; 206 + struct fc_port *rport; 205 207 206 208 down(&zfcp_data.config_sema); 207 209 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 + } 208 218 zfcp_erp_adapter_shutdown(adapter, 0); 209 219 zfcp_erp_wait(adapter); 210 220 zfcp_adapter_scsi_unregister(adapter);
+1 -1
drivers/s390/scsi/zfcp_def.h
··· 906 906 */ 907 907 struct zfcp_port { 908 908 struct device sysfs_device; /* sysfs device */ 909 + struct fc_rport *rport; /* rport of fc transport class */ 909 910 struct list_head list; /* list of remote ports */ 910 911 atomic_t refcount; /* reference count */ 911 912 wait_queue_head_t remove_wq; /* can be used to wait for ··· 917 916 list */ 918 917 u32 units; /* # of logical units in list */ 919 918 atomic_t status; /* status of this remote port */ 920 - scsi_id_t scsi_id; /* own SCSI ID */ 921 919 wwn_t wwnn; /* WWNN if known */ 922 920 wwn_t wwpn; /* WWPN */ 923 921 fc_id_t d_id; /* D_ID */
+22 -3
drivers/s390/scsi/zfcp_erp.c
··· 3360 3360 if ((result == ZFCP_ERP_SUCCEEDED) 3361 3361 && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, 3362 3362 &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); 3366 3368 zfcp_unit_put(unit); 3367 3369 break; 3368 3370 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: 3369 3371 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 + } 3370 3389 zfcp_port_put(port); 3371 3390 break; 3372 3391 case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
+2
drivers/s390/scsi/zfcp_ext.h
··· 143 143 struct scsi_cmnd *, struct timer_list *); 144 144 extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, 145 145 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 *); 146 148 extern struct scsi_transport_template *zfcp_transport_template; 147 149 extern struct fc_function_template zfcp_transport_functions; 148 150
+1
drivers/s390/scsi/zfcp_fsf.c
··· 2062 2062 zfcp_erp_adapter_shutdown(adapter, 0); 2063 2063 return -EIO; 2064 2064 } 2065 + zfcp_set_fc_host_attrs(adapter); 2065 2066 return 0; 2066 2067 } 2067 2068
+20 -5
drivers/s390/scsi/zfcp_scsi.c
··· 389 389 struct zfcp_unit *unit, *retval = NULL; 390 390 391 391 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)) 393 393 continue; 394 394 list_for_each_entry(unit, &port->unit_list_head, list) { 395 395 if (lun == unit->scsi_lun) { ··· 408 408 struct zfcp_port *port; 409 409 410 410 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)) 412 412 return port; 413 413 } 414 414 return (struct zfcp_port *) NULL; ··· 634 634 { 635 635 int retval; 636 636 struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata; 637 - struct Scsi_Host *scsi_host = scpnt->device->host; 638 637 639 638 if (!unit) { 640 639 ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n"); ··· 728 729 { 729 730 int retval = 0; 730 731 struct zfcp_unit *unit; 731 - struct Scsi_Host *scsi_host = scpnt->device->host; 732 732 733 733 unit = (struct zfcp_unit *) scpnt->device->hostdata; 734 734 ZFCP_LOG_NORMAL("bus reset because of problems with " ··· 751 753 { 752 754 int retval = 0; 753 755 struct zfcp_unit *unit; 754 - struct Scsi_Host *scsi_host = scpnt->device->host; 755 756 756 757 unit = (struct zfcp_unit *) scpnt->device->hostdata; 757 758 ZFCP_LOG_NORMAL("host reset because of problems with " ··· 830 833 shost = adapter->scsi_host; 831 834 if (!shost) 832 835 return; 836 + fc_remove_host(shost); 833 837 scsi_remove_host(shost); 834 838 scsi_host_put(shost); 835 839 adapter->scsi_host = NULL; ··· 904 906 read_unlock_irqrestore(&zfcp_data.config_lock, flags); 905 907 } 906 908 909 + void 910 + zfcp_set_fc_host_attrs(struct zfcp_adapter *adapter) 911 + { 912 + struct Scsi_Host *shost = adapter->scsi_host; 913 + 914 + fc_host_node_name(shost) = adapter->wwnn; 915 + fc_host_port_name(shost) = adapter->wwpn; 916 + strncpy(fc_host_serial_number(shost), adapter->serial_number, 917 + min(FC_SERIAL_NUMBER_SIZE, 32)); 918 + fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; 919 + } 920 + 907 921 struct fc_function_template zfcp_transport_functions = { 908 922 .get_starget_port_id = zfcp_get_port_id, 909 923 .get_starget_port_name = zfcp_get_port_name, ··· 923 913 .show_starget_port_id = 1, 924 914 .show_starget_port_name = 1, 925 915 .show_starget_node_name = 1, 916 + .show_rport_supported_classes = 1, 917 + .show_host_node_name = 1, 918 + .show_host_port_name = 1, 919 + .show_host_supported_classes = 1, 920 + .show_host_serial_number = 1, 926 921 }; 927 922 928 923 /**