diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-10 13:53:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-10 13:53:26 -0400 |
commit | ef5bef357cdf49f3a386c7102dbf3be5f7e5c913 (patch) | |
tree | 48d9dc86768e3e146267ea21d0c898f9008275a1 /drivers/s390 | |
parent | e26feff647ef34423b048b940540a0059001ddb0 (diff) | |
parent | 41bfcf90101601f9507240ff0435c1b73d28a132 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (37 commits)
[SCSI] zfcp: fix double dbf id usage
[SCSI] zfcp: wait on SCSI work to be finished before proceeding with init dev
[SCSI] zfcp: fix erp list usage without using locks
[SCSI] zfcp: prevent fc_remote_port_delete calls for unregistered rport
[SCSI] zfcp: fix deadlock caused by shared work queue tasks
[SCSI] zfcp: put threshold data in hba trace
[SCSI] zfcp: Simplify zfcp data structures
[SCSI] zfcp: Simplify get_adapter_by_busid
[SCSI] zfcp: remove all typedefs and replace them with standards
[SCSI] zfcp: attach and release SAN nameserver port on demand
[SCSI] zfcp: remove unused references, declarations and flags
[SCSI] zfcp: Update message with input from review
[SCSI] zfcp: add queue_full sysfs attribute
[SCSI] scsi_dh: suppress comparison warning
[SCSI] scsi_dh: add Dell product information into rdac device handler
[SCSI] qla2xxx: remove the unused SCSI_QLOGIC_FC_FIRMWARE option
[SCSI] qla2xxx: fix printk format warnings
[SCSI] qla2xxx: Update version number to 8.02.01-k8.
[SCSI] qla2xxx: Ignore payload reserved-bits during RSCN processing.
[SCSI] qla2xxx: Additional residual-count corrections during UNDERRUN handling.
...
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 150 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ccw.c | 45 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 75 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 179 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 229 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 27 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 227 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 584 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.h | 75 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 67 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 28 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 60 |
13 files changed, 812 insertions, 935 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 90abfd06ed55..24255e42dc30 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -88,11 +88,13 @@ static int __init zfcp_device_setup(char *devstr) | |||
88 | strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE); | 88 | strncpy(zfcp_data.init_busid, token, BUS_ID_SIZE); |
89 | 89 | ||
90 | token = strsep(&str, ","); | 90 | token = strsep(&str, ","); |
91 | if (!token || strict_strtoull(token, 0, &zfcp_data.init_wwpn)) | 91 | if (!token || strict_strtoull(token, 0, |
92 | (unsigned long long *) &zfcp_data.init_wwpn)) | ||
92 | goto err_out; | 93 | goto err_out; |
93 | 94 | ||
94 | token = strsep(&str, ","); | 95 | token = strsep(&str, ","); |
95 | if (!token || strict_strtoull(token, 0, &zfcp_data.init_fcp_lun)) | 96 | if (!token || strict_strtoull(token, 0, |
97 | (unsigned long long *) &zfcp_data.init_fcp_lun)) | ||
96 | goto err_out; | 98 | goto err_out; |
97 | 99 | ||
98 | kfree(str); | 100 | kfree(str); |
@@ -100,24 +102,10 @@ static int __init zfcp_device_setup(char *devstr) | |||
100 | 102 | ||
101 | err_out: | 103 | err_out: |
102 | kfree(str); | 104 | kfree(str); |
103 | pr_err("zfcp: Parse error for device parameter string %s, " | 105 | pr_err("zfcp: %s is not a valid SCSI device\n", devstr); |
104 | "device not attached.\n", devstr); | ||
105 | return 0; | 106 | return 0; |
106 | } | 107 | } |
107 | 108 | ||
108 | static struct zfcp_adapter *zfcp_get_adapter_by_busid(char *bus_id) | ||
109 | { | ||
110 | struct zfcp_adapter *adapter; | ||
111 | |||
112 | list_for_each_entry(adapter, &zfcp_data.adapter_list_head, list) | ||
113 | if ((strncmp(bus_id, adapter->ccw_device->dev.bus_id, | ||
114 | BUS_ID_SIZE) == 0) && | ||
115 | !(atomic_read(&adapter->status) & | ||
116 | ZFCP_STATUS_COMMON_REMOVE)) | ||
117 | return adapter; | ||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | static void __init zfcp_init_device_configure(void) | 109 | static void __init zfcp_init_device_configure(void) |
122 | { | 110 | { |
123 | struct zfcp_adapter *adapter; | 111 | struct zfcp_adapter *adapter; |
@@ -141,7 +129,12 @@ static void __init zfcp_init_device_configure(void) | |||
141 | goto out_unit; | 129 | goto out_unit; |
142 | up(&zfcp_data.config_sema); | 130 | up(&zfcp_data.config_sema); |
143 | ccw_device_set_online(adapter->ccw_device); | 131 | ccw_device_set_online(adapter->ccw_device); |
132 | |||
144 | zfcp_erp_wait(adapter); | 133 | zfcp_erp_wait(adapter); |
134 | wait_event(adapter->erp_done_wqh, | ||
135 | !(atomic_read(&unit->status) & | ||
136 | ZFCP_STATUS_UNIT_SCSI_WORK_PENDING)); | ||
137 | |||
145 | down(&zfcp_data.config_sema); | 138 | down(&zfcp_data.config_sema); |
146 | zfcp_unit_put(unit); | 139 | zfcp_unit_put(unit); |
147 | out_unit: | 140 | out_unit: |
@@ -180,9 +173,9 @@ static int __init zfcp_module_init(void) | |||
180 | if (!zfcp_data.gid_pn_cache) | 173 | if (!zfcp_data.gid_pn_cache) |
181 | goto out_gid_cache; | 174 | goto out_gid_cache; |
182 | 175 | ||
183 | INIT_LIST_HEAD(&zfcp_data.adapter_list_head); | 176 | zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq"); |
184 | INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh); | ||
185 | 177 | ||
178 | INIT_LIST_HEAD(&zfcp_data.adapter_list_head); | ||
186 | sema_init(&zfcp_data.config_sema, 1); | 179 | sema_init(&zfcp_data.config_sema, 1); |
187 | rwlock_init(&zfcp_data.config_lock); | 180 | rwlock_init(&zfcp_data.config_lock); |
188 | 181 | ||
@@ -193,13 +186,14 @@ static int __init zfcp_module_init(void) | |||
193 | 186 | ||
194 | retval = misc_register(&zfcp_cfdc_misc); | 187 | retval = misc_register(&zfcp_cfdc_misc); |
195 | if (retval) { | 188 | if (retval) { |
196 | pr_err("zfcp: registration of misc device zfcp_cfdc failed\n"); | 189 | pr_err("zfcp: Registering the misc device zfcp_cfdc failed\n"); |
197 | goto out_misc; | 190 | goto out_misc; |
198 | } | 191 | } |
199 | 192 | ||
200 | retval = zfcp_ccw_register(); | 193 | retval = zfcp_ccw_register(); |
201 | if (retval) { | 194 | if (retval) { |
202 | pr_err("zfcp: Registration with common I/O layer failed.\n"); | 195 | pr_err("zfcp: The zfcp device driver could not register with " |
196 | "the common I/O layer\n"); | ||
203 | goto out_ccw_register; | 197 | goto out_ccw_register; |
204 | } | 198 | } |
205 | 199 | ||
@@ -231,8 +225,7 @@ module_init(zfcp_module_init); | |||
231 | * | 225 | * |
232 | * Returns: pointer to zfcp_unit or NULL | 226 | * Returns: pointer to zfcp_unit or NULL |
233 | */ | 227 | */ |
234 | struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, | 228 | struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, u64 fcp_lun) |
235 | fcp_lun_t fcp_lun) | ||
236 | { | 229 | { |
237 | struct zfcp_unit *unit; | 230 | struct zfcp_unit *unit; |
238 | 231 | ||
@@ -251,7 +244,7 @@ struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *port, | |||
251 | * Returns: pointer to zfcp_port or NULL | 244 | * Returns: pointer to zfcp_port or NULL |
252 | */ | 245 | */ |
253 | struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, | 246 | struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter, |
254 | wwn_t wwpn) | 247 | u64 wwpn) |
255 | { | 248 | { |
256 | struct zfcp_port *port; | 249 | struct zfcp_port *port; |
257 | 250 | ||
@@ -276,7 +269,7 @@ static void zfcp_sysfs_unit_release(struct device *dev) | |||
276 | * | 269 | * |
277 | * Sets up some unit internal structures and creates sysfs entry. | 270 | * Sets up some unit internal structures and creates sysfs entry. |
278 | */ | 271 | */ |
279 | struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) | 272 | struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun) |
280 | { | 273 | { |
281 | struct zfcp_unit *unit; | 274 | struct zfcp_unit *unit; |
282 | 275 | ||
@@ -290,7 +283,8 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) | |||
290 | unit->port = port; | 283 | unit->port = port; |
291 | unit->fcp_lun = fcp_lun; | 284 | unit->fcp_lun = fcp_lun; |
292 | 285 | ||
293 | snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", fcp_lun); | 286 | snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", |
287 | (unsigned long long) fcp_lun); | ||
294 | unit->sysfs_device.parent = &port->sysfs_device; | 288 | unit->sysfs_device.parent = &port->sysfs_device; |
295 | unit->sysfs_device.release = zfcp_sysfs_unit_release; | 289 | unit->sysfs_device.release = zfcp_sysfs_unit_release; |
296 | dev_set_drvdata(&unit->sysfs_device, unit); | 290 | dev_set_drvdata(&unit->sysfs_device, unit); |
@@ -323,7 +317,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) | |||
323 | } | 317 | } |
324 | 318 | ||
325 | zfcp_unit_get(unit); | 319 | zfcp_unit_get(unit); |
326 | unit->scsi_lun = scsilun_to_int((struct scsi_lun *)&unit->fcp_lun); | ||
327 | 320 | ||
328 | write_lock_irq(&zfcp_data.config_lock); | 321 | write_lock_irq(&zfcp_data.config_lock); |
329 | list_add_tail(&unit->list, &port->unit_list_head); | 322 | list_add_tail(&unit->list, &port->unit_list_head); |
@@ -332,7 +325,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) | |||
332 | 325 | ||
333 | write_unlock_irq(&zfcp_data.config_lock); | 326 | write_unlock_irq(&zfcp_data.config_lock); |
334 | 327 | ||
335 | port->units++; | ||
336 | zfcp_port_get(port); | 328 | zfcp_port_get(port); |
337 | 329 | ||
338 | return unit; | 330 | return unit; |
@@ -351,11 +343,10 @@ err_out_free: | |||
351 | */ | 343 | */ |
352 | void zfcp_unit_dequeue(struct zfcp_unit *unit) | 344 | void zfcp_unit_dequeue(struct zfcp_unit *unit) |
353 | { | 345 | { |
354 | zfcp_unit_wait(unit); | 346 | wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0); |
355 | write_lock_irq(&zfcp_data.config_lock); | 347 | write_lock_irq(&zfcp_data.config_lock); |
356 | list_del(&unit->list); | 348 | list_del(&unit->list); |
357 | write_unlock_irq(&zfcp_data.config_lock); | 349 | write_unlock_irq(&zfcp_data.config_lock); |
358 | unit->port->units--; | ||
359 | zfcp_port_put(unit->port); | 350 | zfcp_port_put(unit->port); |
360 | sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs); | 351 | sysfs_remove_group(&unit->sysfs_device.kobj, &zfcp_sysfs_unit_attrs); |
361 | device_unregister(&unit->sysfs_device); | 352 | device_unregister(&unit->sysfs_device); |
@@ -416,11 +407,6 @@ static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) | |||
416 | mempool_destroy(adapter->pool.data_gid_pn); | 407 | mempool_destroy(adapter->pool.data_gid_pn); |
417 | } | 408 | } |
418 | 409 | ||
419 | static void zfcp_dummy_release(struct device *dev) | ||
420 | { | ||
421 | return; | ||
422 | } | ||
423 | |||
424 | /** | 410 | /** |
425 | * zfcp_status_read_refill - refill the long running status_read_requests | 411 | * zfcp_status_read_refill - refill the long running status_read_requests |
426 | * @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled | 412 | * @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled |
@@ -450,19 +436,6 @@ static void _zfcp_status_read_scheduler(struct work_struct *work) | |||
450 | stat_work)); | 436 | stat_work)); |
451 | } | 437 | } |
452 | 438 | ||
453 | static int zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) | ||
454 | { | ||
455 | struct zfcp_port *port; | ||
456 | |||
457 | port = zfcp_port_enqueue(adapter, 0, ZFCP_STATUS_PORT_WKA, | ||
458 | ZFCP_DID_DIRECTORY_SERVICE); | ||
459 | if (IS_ERR(port)) | ||
460 | return PTR_ERR(port); | ||
461 | zfcp_port_put(port); | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | /** | 439 | /** |
467 | * zfcp_adapter_enqueue - enqueue a new adapter to the list | 440 | * zfcp_adapter_enqueue - enqueue a new adapter to the list |
468 | * @ccw_device: pointer to the struct cc_device | 441 | * @ccw_device: pointer to the struct cc_device |
@@ -508,7 +481,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
508 | init_waitqueue_head(&adapter->erp_done_wqh); | 481 | init_waitqueue_head(&adapter->erp_done_wqh); |
509 | 482 | ||
510 | INIT_LIST_HEAD(&adapter->port_list_head); | 483 | INIT_LIST_HEAD(&adapter->port_list_head); |
511 | INIT_LIST_HEAD(&adapter->port_remove_lh); | ||
512 | INIT_LIST_HEAD(&adapter->erp_ready_head); | 484 | INIT_LIST_HEAD(&adapter->erp_ready_head); |
513 | INIT_LIST_HEAD(&adapter->erp_running_head); | 485 | INIT_LIST_HEAD(&adapter->erp_running_head); |
514 | 486 | ||
@@ -518,7 +490,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
518 | spin_lock_init(&adapter->san_dbf_lock); | 490 | spin_lock_init(&adapter->san_dbf_lock); |
519 | spin_lock_init(&adapter->scsi_dbf_lock); | 491 | spin_lock_init(&adapter->scsi_dbf_lock); |
520 | spin_lock_init(&adapter->rec_dbf_lock); | 492 | spin_lock_init(&adapter->rec_dbf_lock); |
521 | spin_lock_init(&adapter->req_q.lock); | 493 | spin_lock_init(&adapter->req_q_lock); |
522 | 494 | ||
523 | rwlock_init(&adapter->erp_lock); | 495 | rwlock_init(&adapter->erp_lock); |
524 | rwlock_init(&adapter->abort_lock); | 496 | rwlock_init(&adapter->abort_lock); |
@@ -537,28 +509,15 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
537 | &zfcp_sysfs_adapter_attrs)) | 509 | &zfcp_sysfs_adapter_attrs)) |
538 | goto sysfs_failed; | 510 | goto sysfs_failed; |
539 | 511 | ||
540 | adapter->generic_services.parent = &adapter->ccw_device->dev; | ||
541 | adapter->generic_services.release = zfcp_dummy_release; | ||
542 | snprintf(adapter->generic_services.bus_id, BUS_ID_SIZE, | ||
543 | "generic_services"); | ||
544 | |||
545 | if (device_register(&adapter->generic_services)) | ||
546 | goto generic_services_failed; | ||
547 | |||
548 | write_lock_irq(&zfcp_data.config_lock); | 512 | write_lock_irq(&zfcp_data.config_lock); |
549 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); | 513 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); |
550 | list_add_tail(&adapter->list, &zfcp_data.adapter_list_head); | 514 | list_add_tail(&adapter->list, &zfcp_data.adapter_list_head); |
551 | write_unlock_irq(&zfcp_data.config_lock); | 515 | write_unlock_irq(&zfcp_data.config_lock); |
552 | 516 | ||
553 | zfcp_data.adapters++; | 517 | zfcp_fc_nameserver_init(adapter); |
554 | |||
555 | zfcp_nameserver_enqueue(adapter); | ||
556 | 518 | ||
557 | return 0; | 519 | return 0; |
558 | 520 | ||
559 | generic_services_failed: | ||
560 | sysfs_remove_group(&ccw_device->dev.kobj, | ||
561 | &zfcp_sysfs_adapter_attrs); | ||
562 | sysfs_failed: | 521 | sysfs_failed: |
563 | zfcp_adapter_debug_unregister(adapter); | 522 | zfcp_adapter_debug_unregister(adapter); |
564 | debug_register_failed: | 523 | debug_register_failed: |
@@ -585,7 +544,6 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
585 | cancel_work_sync(&adapter->scan_work); | 544 | cancel_work_sync(&adapter->scan_work); |
586 | cancel_work_sync(&adapter->stat_work); | 545 | cancel_work_sync(&adapter->stat_work); |
587 | zfcp_adapter_scsi_unregister(adapter); | 546 | zfcp_adapter_scsi_unregister(adapter); |
588 | device_unregister(&adapter->generic_services); | ||
589 | sysfs_remove_group(&adapter->ccw_device->dev.kobj, | 547 | sysfs_remove_group(&adapter->ccw_device->dev.kobj, |
590 | &zfcp_sysfs_adapter_attrs); | 548 | &zfcp_sysfs_adapter_attrs); |
591 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); | 549 | dev_set_drvdata(&adapter->ccw_device->dev, NULL); |
@@ -603,9 +561,6 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
603 | list_del(&adapter->list); | 561 | list_del(&adapter->list); |
604 | write_unlock_irq(&zfcp_data.config_lock); | 562 | write_unlock_irq(&zfcp_data.config_lock); |
605 | 563 | ||
606 | /* decrease number of adapters in list */ | ||
607 | zfcp_data.adapters--; | ||
608 | |||
609 | zfcp_qdio_free(adapter); | 564 | zfcp_qdio_free(adapter); |
610 | 565 | ||
611 | zfcp_free_low_mem_buffers(adapter); | 566 | zfcp_free_low_mem_buffers(adapter); |
@@ -633,21 +588,19 @@ static void zfcp_sysfs_port_release(struct device *dev) | |||
633 | * d_id is used to enqueue ports with a well known address like the Directory | 588 | * d_id is used to enqueue ports with a well known address like the Directory |
634 | * Service for nameserver lookup. | 589 | * Service for nameserver lookup. |
635 | */ | 590 | */ |
636 | struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | 591 | struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, |
637 | u32 status, u32 d_id) | 592 | u32 status, u32 d_id) |
638 | { | 593 | { |
639 | struct zfcp_port *port; | 594 | struct zfcp_port *port; |
640 | int retval; | 595 | int retval; |
641 | char *bus_id; | ||
642 | 596 | ||
643 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); | 597 | port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); |
644 | if (!port) | 598 | if (!port) |
645 | return ERR_PTR(-ENOMEM); | 599 | return ERR_PTR(-ENOMEM); |
646 | 600 | ||
647 | init_waitqueue_head(&port->remove_wq); | 601 | init_waitqueue_head(&port->remove_wq); |
648 | |||
649 | INIT_LIST_HEAD(&port->unit_list_head); | 602 | INIT_LIST_HEAD(&port->unit_list_head); |
650 | INIT_LIST_HEAD(&port->unit_remove_lh); | 603 | INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup); |
651 | 604 | ||
652 | port->adapter = adapter; | 605 | port->adapter = adapter; |
653 | port->d_id = d_id; | 606 | port->d_id = d_id; |
@@ -657,34 +610,9 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
657 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); | 610 | atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status); |
658 | atomic_set(&port->refcount, 0); | 611 | atomic_set(&port->refcount, 0); |
659 | 612 | ||
660 | if (status & ZFCP_STATUS_PORT_WKA) { | 613 | snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", |
661 | switch (d_id) { | 614 | (unsigned long long) wwpn); |
662 | case ZFCP_DID_DIRECTORY_SERVICE: | 615 | port->sysfs_device.parent = &adapter->ccw_device->dev; |
663 | bus_id = "directory"; | ||
664 | break; | ||
665 | case ZFCP_DID_MANAGEMENT_SERVICE: | ||
666 | bus_id = "management"; | ||
667 | break; | ||
668 | case ZFCP_DID_KEY_DISTRIBUTION_SERVICE: | ||
669 | bus_id = "key_distribution"; | ||
670 | break; | ||
671 | case ZFCP_DID_ALIAS_SERVICE: | ||
672 | bus_id = "alias"; | ||
673 | break; | ||
674 | case ZFCP_DID_TIME_SERVICE: | ||
675 | bus_id = "time"; | ||
676 | break; | ||
677 | default: | ||
678 | kfree(port); | ||
679 | return ERR_PTR(-EINVAL); | ||
680 | } | ||
681 | snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE, "%s", bus_id); | ||
682 | port->sysfs_device.parent = &adapter->generic_services; | ||
683 | } else { | ||
684 | snprintf(port->sysfs_device.bus_id, | ||
685 | BUS_ID_SIZE, "0x%016llx", wwpn); | ||
686 | port->sysfs_device.parent = &adapter->ccw_device->dev; | ||
687 | } | ||
688 | 616 | ||
689 | port->sysfs_device.release = zfcp_sysfs_port_release; | 617 | port->sysfs_device.release = zfcp_sysfs_port_release; |
690 | dev_set_drvdata(&port->sysfs_device, port); | 618 | dev_set_drvdata(&port->sysfs_device, port); |
@@ -700,12 +628,8 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
700 | if (device_register(&port->sysfs_device)) | 628 | if (device_register(&port->sysfs_device)) |
701 | goto err_out_free; | 629 | goto err_out_free; |
702 | 630 | ||
703 | if (status & ZFCP_STATUS_PORT_WKA) | 631 | retval = sysfs_create_group(&port->sysfs_device.kobj, |
704 | retval = sysfs_create_group(&port->sysfs_device.kobj, | 632 | &zfcp_sysfs_port_attrs); |
705 | &zfcp_sysfs_ns_port_attrs); | ||
706 | else | ||
707 | retval = sysfs_create_group(&port->sysfs_device.kobj, | ||
708 | &zfcp_sysfs_port_attrs); | ||
709 | 633 | ||
710 | if (retval) { | 634 | if (retval) { |
711 | device_unregister(&port->sysfs_device); | 635 | device_unregister(&port->sysfs_device); |
@@ -718,10 +642,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, | |||
718 | list_add_tail(&port->list, &adapter->port_list_head); | 642 | list_add_tail(&port->list, &adapter->port_list_head); |
719 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | 643 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); |
720 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); | 644 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); |
721 | if (d_id == ZFCP_DID_DIRECTORY_SERVICE) | ||
722 | if (!adapter->nameserver_port) | ||
723 | adapter->nameserver_port = port; | ||
724 | adapter->ports++; | ||
725 | 645 | ||
726 | write_unlock_irq(&zfcp_data.config_lock); | 646 | write_unlock_irq(&zfcp_data.config_lock); |
727 | 647 | ||
@@ -740,21 +660,15 @@ err_out: | |||
740 | */ | 660 | */ |
741 | void zfcp_port_dequeue(struct zfcp_port *port) | 661 | void zfcp_port_dequeue(struct zfcp_port *port) |
742 | { | 662 | { |
743 | zfcp_port_wait(port); | 663 | wait_event(port->remove_wq, atomic_read(&port->refcount) == 0); |
744 | write_lock_irq(&zfcp_data.config_lock); | 664 | write_lock_irq(&zfcp_data.config_lock); |
745 | list_del(&port->list); | 665 | list_del(&port->list); |
746 | port->adapter->ports--; | ||
747 | write_unlock_irq(&zfcp_data.config_lock); | 666 | write_unlock_irq(&zfcp_data.config_lock); |
748 | if (port->rport) | 667 | if (port->rport) |
749 | fc_remote_port_delete(port->rport); | 668 | fc_remote_port_delete(port->rport); |
750 | port->rport = NULL; | 669 | port->rport = NULL; |
751 | zfcp_adapter_put(port->adapter); | 670 | zfcp_adapter_put(port->adapter); |
752 | if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA) | 671 | sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs); |
753 | sysfs_remove_group(&port->sysfs_device.kobj, | ||
754 | &zfcp_sysfs_ns_port_attrs); | ||
755 | else | ||
756 | sysfs_remove_group(&port->sysfs_device.kobj, | ||
757 | &zfcp_sysfs_port_attrs); | ||
758 | device_unregister(&port->sysfs_device); | 672 | device_unregister(&port->sysfs_device); |
759 | } | 673 | } |
760 | 674 | ||
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 51b6a05f4d12..b04038c74786 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -25,7 +25,8 @@ static int zfcp_ccw_probe(struct ccw_device *ccw_device) | |||
25 | down(&zfcp_data.config_sema); | 25 | down(&zfcp_data.config_sema); |
26 | if (zfcp_adapter_enqueue(ccw_device)) { | 26 | if (zfcp_adapter_enqueue(ccw_device)) { |
27 | dev_err(&ccw_device->dev, | 27 | dev_err(&ccw_device->dev, |
28 | "Setup of data structures failed.\n"); | 28 | "Setting up data structures for the " |
29 | "FCP adapter failed\n"); | ||
29 | retval = -EINVAL; | 30 | retval = -EINVAL; |
30 | } | 31 | } |
31 | up(&zfcp_data.config_sema); | 32 | up(&zfcp_data.config_sema); |
@@ -46,6 +47,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
46 | struct zfcp_adapter *adapter; | 47 | struct zfcp_adapter *adapter; |
47 | struct zfcp_port *port, *p; | 48 | struct zfcp_port *port, *p; |
48 | struct zfcp_unit *unit, *u; | 49 | struct zfcp_unit *unit, *u; |
50 | LIST_HEAD(unit_remove_lh); | ||
51 | LIST_HEAD(port_remove_lh); | ||
49 | 52 | ||
50 | ccw_device_set_offline(ccw_device); | 53 | ccw_device_set_offline(ccw_device); |
51 | down(&zfcp_data.config_sema); | 54 | down(&zfcp_data.config_sema); |
@@ -54,26 +57,26 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device) | |||
54 | write_lock_irq(&zfcp_data.config_lock); | 57 | write_lock_irq(&zfcp_data.config_lock); |
55 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { | 58 | list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { |
56 | list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { | 59 | list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { |
57 | list_move(&unit->list, &port->unit_remove_lh); | 60 | list_move(&unit->list, &unit_remove_lh); |
58 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, | 61 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, |
59 | &unit->status); | 62 | &unit->status); |
60 | } | 63 | } |
61 | list_move(&port->list, &adapter->port_remove_lh); | 64 | list_move(&port->list, &port_remove_lh); |
62 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | 65 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); |
63 | } | 66 | } |
64 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); | 67 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); |
65 | write_unlock_irq(&zfcp_data.config_lock); | 68 | write_unlock_irq(&zfcp_data.config_lock); |
66 | 69 | ||
67 | list_for_each_entry_safe(port, p, &adapter->port_remove_lh, list) { | 70 | list_for_each_entry_safe(port, p, &port_remove_lh, list) { |
68 | list_for_each_entry_safe(unit, u, &port->unit_remove_lh, list) { | 71 | list_for_each_entry_safe(unit, u, &unit_remove_lh, list) { |
69 | if (atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED, | 72 | if (atomic_read(&unit->status) & |
70 | &unit->status)) | 73 | ZFCP_STATUS_UNIT_REGISTERED) |
71 | scsi_remove_device(unit->device); | 74 | scsi_remove_device(unit->device); |
72 | zfcp_unit_dequeue(unit); | 75 | zfcp_unit_dequeue(unit); |
73 | } | 76 | } |
74 | zfcp_port_dequeue(port); | 77 | zfcp_port_dequeue(port); |
75 | } | 78 | } |
76 | zfcp_adapter_wait(adapter); | 79 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); |
77 | zfcp_adapter_dequeue(adapter); | 80 | zfcp_adapter_dequeue(adapter); |
78 | 81 | ||
79 | up(&zfcp_data.config_sema); | 82 | up(&zfcp_data.config_sema); |
@@ -156,15 +159,18 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) | |||
156 | 159 | ||
157 | switch (event) { | 160 | switch (event) { |
158 | case CIO_GONE: | 161 | case CIO_GONE: |
159 | dev_warn(&adapter->ccw_device->dev, "device gone\n"); | 162 | dev_warn(&adapter->ccw_device->dev, |
163 | "The FCP device has been detached\n"); | ||
160 | zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); | 164 | zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); |
161 | break; | 165 | break; |
162 | case CIO_NO_PATH: | 166 | case CIO_NO_PATH: |
163 | dev_warn(&adapter->ccw_device->dev, "no path\n"); | 167 | dev_warn(&adapter->ccw_device->dev, |
168 | "The CHPID for the FCP device is offline\n"); | ||
164 | zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); | 169 | zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); |
165 | break; | 170 | break; |
166 | case CIO_OPER: | 171 | case CIO_OPER: |
167 | dev_info(&adapter->ccw_device->dev, "operational again\n"); | 172 | dev_info(&adapter->ccw_device->dev, |
173 | "The FCP device is operational again\n"); | ||
168 | zfcp_erp_modify_adapter_status(adapter, 11, NULL, | 174 | zfcp_erp_modify_adapter_status(adapter, 11, NULL, |
169 | ZFCP_STATUS_COMMON_RUNNING, | 175 | ZFCP_STATUS_COMMON_RUNNING, |
170 | ZFCP_SET); | 176 | ZFCP_SET); |
@@ -220,3 +226,20 @@ int __init zfcp_ccw_register(void) | |||
220 | { | 226 | { |
221 | return ccw_driver_register(&zfcp_ccw_driver); | 227 | return ccw_driver_register(&zfcp_ccw_driver); |
222 | } | 228 | } |
229 | |||
230 | /** | ||
231 | * zfcp_get_adapter_by_busid - find zfcp_adapter struct | ||
232 | * @busid: bus id string of zfcp adapter to find | ||
233 | */ | ||
234 | struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid) | ||
235 | { | ||
236 | struct ccw_device *ccw_device; | ||
237 | struct zfcp_adapter *adapter = NULL; | ||
238 | |||
239 | ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); | ||
240 | if (ccw_device) { | ||
241 | adapter = dev_get_drvdata(&ccw_device->dev); | ||
242 | put_device(&ccw_device->dev); | ||
243 | } | ||
244 | return adapter; | ||
245 | } | ||
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index fca48b88fc53..060f5f2352ec 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -318,6 +318,26 @@ void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, | |||
318 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | 318 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); |
319 | } | 319 | } |
320 | 320 | ||
321 | /** | ||
322 | * zfcp_hba_dbf_event_berr - trace event for bit error threshold | ||
323 | * @adapter: adapter affected by this QDIO related event | ||
324 | * @req: fsf request | ||
325 | */ | ||
326 | void zfcp_hba_dbf_event_berr(struct zfcp_adapter *adapter, | ||
327 | struct zfcp_fsf_req *req) | ||
328 | { | ||
329 | struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf; | ||
330 | struct fsf_status_read_buffer *sr_buf = req->data; | ||
331 | struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error; | ||
332 | unsigned long flags; | ||
333 | |||
334 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); | ||
335 | memset(r, 0, sizeof(*r)); | ||
336 | strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE); | ||
337 | memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload)); | ||
338 | debug_event(adapter->hba_dbf, 0, r, sizeof(*r)); | ||
339 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | ||
340 | } | ||
321 | static void zfcp_hba_dbf_view_response(char **p, | 341 | static void zfcp_hba_dbf_view_response(char **p, |
322 | struct zfcp_hba_dbf_record_response *r) | 342 | struct zfcp_hba_dbf_record_response *r) |
323 | { | 343 | { |
@@ -399,6 +419,30 @@ static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r) | |||
399 | zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count); | 419 | zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count); |
400 | } | 420 | } |
401 | 421 | ||
422 | static void zfcp_hba_dbf_view_berr(char **p, struct fsf_bit_error_payload *r) | ||
423 | { | ||
424 | zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count); | ||
425 | zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count); | ||
426 | zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count); | ||
427 | zfcp_dbf_out(p, "prim_seq_err", "%d", | ||
428 | r->primitive_sequence_error_count); | ||
429 | zfcp_dbf_out(p, "inval_trans_word_err", "%d", | ||
430 | r->invalid_transmission_word_error_count); | ||
431 | zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count); | ||
432 | zfcp_dbf_out(p, "prim_seq_event_to", "%d", | ||
433 | r->primitive_sequence_event_timeout_count); | ||
434 | zfcp_dbf_out(p, "elast_buf_overrun_err", "%d", | ||
435 | r->elastic_buffer_overrun_error_count); | ||
436 | zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d", | ||
437 | r->advertised_receive_b2b_credit); | ||
438 | zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d", | ||
439 | r->current_receive_b2b_credit); | ||
440 | zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d", | ||
441 | r->advertised_transmit_b2b_credit); | ||
442 | zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d", | ||
443 | r->current_transmit_b2b_credit); | ||
444 | } | ||
445 | |||
402 | static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view, | 446 | static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view, |
403 | char *out_buf, const char *in_buf) | 447 | char *out_buf, const char *in_buf) |
404 | { | 448 | { |
@@ -418,6 +462,8 @@ static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view, | |||
418 | zfcp_hba_dbf_view_status(&p, &r->u.status); | 462 | zfcp_hba_dbf_view_status(&p, &r->u.status); |
419 | else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) | 463 | else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) |
420 | zfcp_hba_dbf_view_qdio(&p, &r->u.qdio); | 464 | zfcp_hba_dbf_view_qdio(&p, &r->u.qdio); |
465 | else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0) | ||
466 | zfcp_hba_dbf_view_berr(&p, &r->u.berr); | ||
421 | 467 | ||
422 | p += sprintf(p, "\n"); | 468 | p += sprintf(p, "\n"); |
423 | return p - out_buf; | 469 | return p - out_buf; |
@@ -519,14 +565,14 @@ static const char *zfcp_rec_dbf_ids[] = { | |||
519 | [75] = "physical port recovery escalation after failed port " | 565 | [75] = "physical port recovery escalation after failed port " |
520 | "recovery", | 566 | "recovery", |
521 | [76] = "port recovery escalation after failed unit recovery", | 567 | [76] = "port recovery escalation after failed unit recovery", |
522 | [77] = "recovery opening nameserver port", | 568 | [77] = "", |
523 | [78] = "duplicate request id", | 569 | [78] = "duplicate request id", |
524 | [79] = "link down", | 570 | [79] = "link down", |
525 | [80] = "exclusive read-only unit access unsupported", | 571 | [80] = "exclusive read-only unit access unsupported", |
526 | [81] = "shared read-write unit access unsupported", | 572 | [81] = "shared read-write unit access unsupported", |
527 | [82] = "incoming rscn", | 573 | [82] = "incoming rscn", |
528 | [83] = "incoming wwpn", | 574 | [83] = "incoming wwpn", |
529 | [84] = "", | 575 | [84] = "wka port handle not valid close port", |
530 | [85] = "online", | 576 | [85] = "online", |
531 | [86] = "offline", | 577 | [86] = "offline", |
532 | [87] = "ccw device gone", | 578 | [87] = "ccw device gone", |
@@ -570,7 +616,7 @@ static const char *zfcp_rec_dbf_ids[] = { | |||
570 | [125] = "need newer zfcp", | 616 | [125] = "need newer zfcp", |
571 | [126] = "need newer microcode", | 617 | [126] = "need newer microcode", |
572 | [127] = "arbitrated loop not supported", | 618 | [127] = "arbitrated loop not supported", |
573 | [128] = "unknown topology", | 619 | [128] = "", |
574 | [129] = "qtcb size mismatch", | 620 | [129] = "qtcb size mismatch", |
575 | [130] = "unknown fsf status ecd", | 621 | [130] = "unknown fsf status ecd", |
576 | [131] = "fcp request too big", | 622 | [131] = "fcp request too big", |
@@ -829,9 +875,9 @@ void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action) | |||
829 | void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | 875 | void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) |
830 | { | 876 | { |
831 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | 877 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; |
832 | struct zfcp_port *port = ct->port; | 878 | struct zfcp_wka_port *wka_port = ct->wka_port; |
833 | struct zfcp_adapter *adapter = port->adapter; | 879 | struct zfcp_adapter *adapter = wka_port->adapter; |
834 | struct ct_hdr *hdr = zfcp_sg_to_address(ct->req); | 880 | struct ct_hdr *hdr = sg_virt(ct->req); |
835 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | 881 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; |
836 | struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; | 882 | struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; |
837 | unsigned long flags; | 883 | unsigned long flags; |
@@ -842,7 +888,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | |||
842 | r->fsf_reqid = (unsigned long)fsf_req; | 888 | r->fsf_reqid = (unsigned long)fsf_req; |
843 | r->fsf_seqno = fsf_req->seq_no; | 889 | r->fsf_seqno = fsf_req->seq_no; |
844 | r->s_id = fc_host_port_id(adapter->scsi_host); | 890 | r->s_id = fc_host_port_id(adapter->scsi_host); |
845 | r->d_id = port->d_id; | 891 | r->d_id = wka_port->d_id; |
846 | oct->cmd_req_code = hdr->cmd_rsp_code; | 892 | oct->cmd_req_code = hdr->cmd_rsp_code; |
847 | oct->revision = hdr->revision; | 893 | oct->revision = hdr->revision; |
848 | oct->gs_type = hdr->gs_type; | 894 | oct->gs_type = hdr->gs_type; |
@@ -863,9 +909,9 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | |||
863 | void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | 909 | void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) |
864 | { | 910 | { |
865 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | 911 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; |
866 | struct zfcp_port *port = ct->port; | 912 | struct zfcp_wka_port *wka_port = ct->wka_port; |
867 | struct zfcp_adapter *adapter = port->adapter; | 913 | struct zfcp_adapter *adapter = wka_port->adapter; |
868 | struct ct_hdr *hdr = zfcp_sg_to_address(ct->resp); | 914 | struct ct_hdr *hdr = sg_virt(ct->resp); |
869 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | 915 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; |
870 | struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; | 916 | struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; |
871 | unsigned long flags; | 917 | unsigned long flags; |
@@ -875,7 +921,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | |||
875 | strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); | 921 | strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); |
876 | r->fsf_reqid = (unsigned long)fsf_req; | 922 | r->fsf_reqid = (unsigned long)fsf_req; |
877 | r->fsf_seqno = fsf_req->seq_no; | 923 | r->fsf_seqno = fsf_req->seq_no; |
878 | r->s_id = port->d_id; | 924 | r->s_id = wka_port->d_id; |
879 | r->d_id = fc_host_port_id(adapter->scsi_host); | 925 | r->d_id = fc_host_port_id(adapter->scsi_host); |
880 | rct->cmd_rsp_code = hdr->cmd_rsp_code; | 926 | rct->cmd_rsp_code = hdr->cmd_rsp_code; |
881 | rct->revision = hdr->revision; | 927 | rct->revision = hdr->revision; |
@@ -922,8 +968,8 @@ void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) | |||
922 | 968 | ||
923 | zfcp_san_dbf_event_els("oels", 2, fsf_req, | 969 | zfcp_san_dbf_event_els("oels", 2, fsf_req, |
924 | fc_host_port_id(els->adapter->scsi_host), | 970 | fc_host_port_id(els->adapter->scsi_host), |
925 | els->d_id, *(u8 *) zfcp_sg_to_address(els->req), | 971 | els->d_id, *(u8 *) sg_virt(els->req), |
926 | zfcp_sg_to_address(els->req), els->req->length); | 972 | sg_virt(els->req), els->req->length); |
927 | } | 973 | } |
928 | 974 | ||
929 | /** | 975 | /** |
@@ -936,8 +982,7 @@ void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) | |||
936 | 982 | ||
937 | zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id, | 983 | zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id, |
938 | fc_host_port_id(els->adapter->scsi_host), | 984 | fc_host_port_id(els->adapter->scsi_host), |
939 | *(u8 *)zfcp_sg_to_address(els->req), | 985 | *(u8 *)sg_virt(els->req), sg_virt(els->resp), |
940 | zfcp_sg_to_address(els->resp), | ||
941 | els->resp->length); | 986 | els->resp->length); |
942 | } | 987 | } |
943 | 988 | ||
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index 0ddb18449d11..e8f450801fea 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h | |||
@@ -151,6 +151,7 @@ struct zfcp_hba_dbf_record { | |||
151 | struct zfcp_hba_dbf_record_response response; | 151 | struct zfcp_hba_dbf_record_response response; |
152 | struct zfcp_hba_dbf_record_status status; | 152 | struct zfcp_hba_dbf_record_status status; |
153 | struct zfcp_hba_dbf_record_qdio qdio; | 153 | struct zfcp_hba_dbf_record_qdio qdio; |
154 | struct fsf_bit_error_payload berr; | ||
154 | } u; | 155 | } u; |
155 | } __attribute__ ((packed)); | 156 | } __attribute__ ((packed)); |
156 | 157 | ||
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 67f45fc62f53..73eb41580f25 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -39,29 +39,6 @@ | |||
39 | 39 | ||
40 | /********************* GENERAL DEFINES *********************************/ | 40 | /********************* GENERAL DEFINES *********************************/ |
41 | 41 | ||
42 | /** | ||
43 | * zfcp_sg_to_address - determine kernel address from struct scatterlist | ||
44 | * @list: struct scatterlist | ||
45 | * Return: kernel address | ||
46 | */ | ||
47 | static inline void * | ||
48 | zfcp_sg_to_address(struct scatterlist *list) | ||
49 | { | ||
50 | return sg_virt(list); | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * zfcp_address_to_sg - set up struct scatterlist from kernel address | ||
55 | * @address: kernel address | ||
56 | * @list: struct scatterlist | ||
57 | * @size: buffer size | ||
58 | */ | ||
59 | static inline void | ||
60 | zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) | ||
61 | { | ||
62 | sg_set_buf(list, address, size); | ||
63 | } | ||
64 | |||
65 | #define REQUEST_LIST_SIZE 128 | 42 | #define REQUEST_LIST_SIZE 128 |
66 | 43 | ||
67 | /********************* SCSI SPECIFIC DEFINES *********************************/ | 44 | /********************* SCSI SPECIFIC DEFINES *********************************/ |
@@ -101,11 +78,6 @@ zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size) | |||
101 | 78 | ||
102 | /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ | 79 | /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ |
103 | 80 | ||
104 | typedef unsigned long long wwn_t; | ||
105 | typedef unsigned long long fcp_lun_t; | ||
106 | /* data length field may be at variable position in FCP-2 FCP_CMND IU */ | ||
107 | typedef unsigned int fcp_dl_t; | ||
108 | |||
109 | /* timeout for name-server lookup (in seconds) */ | 81 | /* timeout for name-server lookup (in seconds) */ |
110 | #define ZFCP_NS_GID_PN_TIMEOUT 10 | 82 | #define ZFCP_NS_GID_PN_TIMEOUT 10 |
111 | 83 | ||
@@ -129,7 +101,7 @@ typedef unsigned int fcp_dl_t; | |||
129 | 101 | ||
130 | /* FCP(-2) FCP_CMND IU */ | 102 | /* FCP(-2) FCP_CMND IU */ |
131 | struct fcp_cmnd_iu { | 103 | struct fcp_cmnd_iu { |
132 | fcp_lun_t fcp_lun; /* FCP logical unit number */ | 104 | u64 fcp_lun; /* FCP logical unit number */ |
133 | u8 crn; /* command reference number */ | 105 | u8 crn; /* command reference number */ |
134 | u8 reserved0:5; /* reserved */ | 106 | u8 reserved0:5; /* reserved */ |
135 | u8 task_attribute:3; /* task attribute */ | 107 | u8 task_attribute:3; /* task attribute */ |
@@ -204,7 +176,7 @@ struct fcp_rscn_element { | |||
204 | struct fcp_logo { | 176 | struct fcp_logo { |
205 | u32 command; | 177 | u32 command; |
206 | u32 nport_did; | 178 | u32 nport_did; |
207 | wwn_t nport_wwpn; | 179 | u64 nport_wwpn; |
208 | } __attribute__((packed)); | 180 | } __attribute__((packed)); |
209 | 181 | ||
210 | /* | 182 | /* |
@@ -218,13 +190,6 @@ struct fcp_logo { | |||
218 | #define ZFCP_LS_RSCN 0x61 | 190 | #define ZFCP_LS_RSCN 0x61 |
219 | #define ZFCP_LS_RNID 0x78 | 191 | #define ZFCP_LS_RNID 0x78 |
220 | 192 | ||
221 | struct zfcp_ls_rjt_par { | ||
222 | u8 action; | ||
223 | u8 reason_code; | ||
224 | u8 reason_expl; | ||
225 | u8 vendor_unique; | ||
226 | } __attribute__ ((packed)); | ||
227 | |||
228 | struct zfcp_ls_adisc { | 193 | struct zfcp_ls_adisc { |
229 | u8 code; | 194 | u8 code; |
230 | u8 field[3]; | 195 | u8 field[3]; |
@@ -234,20 +199,6 @@ struct zfcp_ls_adisc { | |||
234 | u32 nport_id; | 199 | u32 nport_id; |
235 | } __attribute__ ((packed)); | 200 | } __attribute__ ((packed)); |
236 | 201 | ||
237 | struct zfcp_ls_adisc_acc { | ||
238 | u8 code; | ||
239 | u8 field[3]; | ||
240 | u32 hard_nport_id; | ||
241 | u64 wwpn; | ||
242 | u64 wwnn; | ||
243 | u32 nport_id; | ||
244 | } __attribute__ ((packed)); | ||
245 | |||
246 | struct zfcp_rc_entry { | ||
247 | u8 code; | ||
248 | const char *description; | ||
249 | }; | ||
250 | |||
251 | /* | 202 | /* |
252 | * FC-GS-2 stuff | 203 | * FC-GS-2 stuff |
253 | */ | 204 | */ |
@@ -281,9 +232,7 @@ struct zfcp_rc_entry { | |||
281 | #define ZFCP_STATUS_COMMON_RUNNING 0x40000000 | 232 | #define ZFCP_STATUS_COMMON_RUNNING 0x40000000 |
282 | #define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000 | 233 | #define ZFCP_STATUS_COMMON_ERP_FAILED 0x20000000 |
283 | #define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000 | 234 | #define ZFCP_STATUS_COMMON_UNBLOCKED 0x10000000 |
284 | #define ZFCP_STATUS_COMMON_OPENING 0x08000000 | ||
285 | #define ZFCP_STATUS_COMMON_OPEN 0x04000000 | 235 | #define ZFCP_STATUS_COMMON_OPEN 0x04000000 |
286 | #define ZFCP_STATUS_COMMON_CLOSING 0x02000000 | ||
287 | #define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000 | 236 | #define ZFCP_STATUS_COMMON_ERP_INUSE 0x01000000 |
288 | #define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000 | 237 | #define ZFCP_STATUS_COMMON_ACCESS_DENIED 0x00800000 |
289 | #define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000 | 238 | #define ZFCP_STATUS_COMMON_ACCESS_BOXED 0x00400000 |
@@ -291,16 +240,15 @@ struct zfcp_rc_entry { | |||
291 | 240 | ||
292 | /* adapter status */ | 241 | /* adapter status */ |
293 | #define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 | 242 | #define ZFCP_STATUS_ADAPTER_QDIOUP 0x00000002 |
294 | #define ZFCP_STATUS_ADAPTER_REGISTERED 0x00000004 | ||
295 | #define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008 | 243 | #define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008 |
296 | #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010 | 244 | #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010 |
297 | #define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP 0x00000020 | 245 | #define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP 0x00000020 |
298 | #define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080 | 246 | #define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080 |
299 | #define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100 | 247 | #define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100 |
300 | #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 | 248 | #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200 |
301 | #define ZFCP_STATUS_ADAPTER_XPORT_OK 0x00000800 | ||
302 | 249 | ||
303 | /* FC-PH/FC-GS well-known address identifiers for generic services */ | 250 | /* FC-PH/FC-GS well-known address identifiers for generic services */ |
251 | #define ZFCP_DID_WKA 0xFFFFF0 | ||
304 | #define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA | 252 | #define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA |
305 | #define ZFCP_DID_TIME_SERVICE 0xFFFFFB | 253 | #define ZFCP_DID_TIME_SERVICE 0xFFFFFB |
306 | #define ZFCP_DID_DIRECTORY_SERVICE 0xFFFFFC | 254 | #define ZFCP_DID_DIRECTORY_SERVICE 0xFFFFFC |
@@ -312,29 +260,27 @@ struct zfcp_rc_entry { | |||
312 | #define ZFCP_STATUS_PORT_DID_DID 0x00000002 | 260 | #define ZFCP_STATUS_PORT_DID_DID 0x00000002 |
313 | #define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004 | 261 | #define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004 |
314 | #define ZFCP_STATUS_PORT_NO_WWPN 0x00000008 | 262 | #define ZFCP_STATUS_PORT_NO_WWPN 0x00000008 |
315 | #define ZFCP_STATUS_PORT_NO_SCSI_ID 0x00000010 | ||
316 | #define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020 | 263 | #define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020 |
317 | 264 | ||
318 | /* for ports with well known addresses */ | 265 | /* well known address (WKA) port status*/ |
319 | #define ZFCP_STATUS_PORT_WKA \ | 266 | enum zfcp_wka_status { |
320 | (ZFCP_STATUS_PORT_NO_WWPN | \ | 267 | ZFCP_WKA_PORT_OFFLINE, |
321 | ZFCP_STATUS_PORT_NO_SCSI_ID) | 268 | ZFCP_WKA_PORT_CLOSING, |
269 | ZFCP_WKA_PORT_OPENING, | ||
270 | ZFCP_WKA_PORT_ONLINE, | ||
271 | }; | ||
322 | 272 | ||
323 | /* logical unit status */ | 273 | /* logical unit status */ |
324 | #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 | ||
325 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 | 274 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 |
326 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 | 275 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 |
327 | #define ZFCP_STATUS_UNIT_REGISTERED 0x00000010 | 276 | #define ZFCP_STATUS_UNIT_REGISTERED 0x00000010 |
328 | #define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING 0x00000020 | 277 | #define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING 0x00000020 |
329 | 278 | ||
330 | /* FSF request status (this does not have a common part) */ | 279 | /* FSF request status (this does not have a common part) */ |
331 | #define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000 | ||
332 | #define ZFCP_STATUS_FSFREQ_POOL 0x00000001 | ||
333 | #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002 | 280 | #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002 |
334 | #define ZFCP_STATUS_FSFREQ_COMPLETED 0x00000004 | 281 | #define ZFCP_STATUS_FSFREQ_COMPLETED 0x00000004 |
335 | #define ZFCP_STATUS_FSFREQ_ERROR 0x00000008 | 282 | #define ZFCP_STATUS_FSFREQ_ERROR 0x00000008 |
336 | #define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010 | 283 | #define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010 |
337 | #define ZFCP_STATUS_FSFREQ_ABORTING 0x00000020 | ||
338 | #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040 | 284 | #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040 |
339 | #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080 | 285 | #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080 |
340 | #define ZFCP_STATUS_FSFREQ_ABORTED 0x00000100 | 286 | #define ZFCP_STATUS_FSFREQ_ABORTED 0x00000100 |
@@ -379,7 +325,7 @@ struct ct_hdr { | |||
379 | * a port name is required */ | 325 | * a port name is required */ |
380 | struct ct_iu_gid_pn_req { | 326 | struct ct_iu_gid_pn_req { |
381 | struct ct_hdr header; | 327 | struct ct_hdr header; |
382 | wwn_t wwpn; | 328 | u64 wwpn; |
383 | } __attribute__ ((packed)); | 329 | } __attribute__ ((packed)); |
384 | 330 | ||
385 | /* FS_ACC IU and data unit for GID_PN nameserver request */ | 331 | /* FS_ACC IU and data unit for GID_PN nameserver request */ |
@@ -388,11 +334,9 @@ struct ct_iu_gid_pn_resp { | |||
388 | u32 d_id; | 334 | u32 d_id; |
389 | } __attribute__ ((packed)); | 335 | } __attribute__ ((packed)); |
390 | 336 | ||
391 | typedef void (*zfcp_send_ct_handler_t)(unsigned long); | ||
392 | |||
393 | /** | 337 | /** |
394 | * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct | 338 | * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct |
395 | * @port: port where the request is sent to | 339 | * @wka_port: port where the request is sent to |
396 | * @req: scatter-gather list for request | 340 | * @req: scatter-gather list for request |
397 | * @resp: scatter-gather list for response | 341 | * @resp: scatter-gather list for response |
398 | * @req_count: number of elements in request scatter-gather list | 342 | * @req_count: number of elements in request scatter-gather list |
@@ -404,12 +348,12 @@ typedef void (*zfcp_send_ct_handler_t)(unsigned long); | |||
404 | * @status: used to pass error status to calling function | 348 | * @status: used to pass error status to calling function |
405 | */ | 349 | */ |
406 | struct zfcp_send_ct { | 350 | struct zfcp_send_ct { |
407 | struct zfcp_port *port; | 351 | struct zfcp_wka_port *wka_port; |
408 | struct scatterlist *req; | 352 | struct scatterlist *req; |
409 | struct scatterlist *resp; | 353 | struct scatterlist *resp; |
410 | unsigned int req_count; | 354 | unsigned int req_count; |
411 | unsigned int resp_count; | 355 | unsigned int resp_count; |
412 | zfcp_send_ct_handler_t handler; | 356 | void (*handler)(unsigned long); |
413 | unsigned long handler_data; | 357 | unsigned long handler_data; |
414 | int timeout; | 358 | int timeout; |
415 | struct completion *completion; | 359 | struct completion *completion; |
@@ -426,8 +370,6 @@ struct zfcp_gid_pn_data { | |||
426 | struct zfcp_port *port; | 370 | struct zfcp_port *port; |
427 | }; | 371 | }; |
428 | 372 | ||
429 | typedef void (*zfcp_send_els_handler_t)(unsigned long); | ||
430 | |||
431 | /** | 373 | /** |
432 | * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els | 374 | * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els |
433 | * @adapter: adapter where request is sent from | 375 | * @adapter: adapter where request is sent from |
@@ -451,22 +393,28 @@ struct zfcp_send_els { | |||
451 | struct scatterlist *resp; | 393 | struct scatterlist *resp; |
452 | unsigned int req_count; | 394 | unsigned int req_count; |
453 | unsigned int resp_count; | 395 | unsigned int resp_count; |
454 | zfcp_send_els_handler_t handler; | 396 | void (*handler)(unsigned long); |
455 | unsigned long handler_data; | 397 | unsigned long handler_data; |
456 | struct completion *completion; | 398 | struct completion *completion; |
457 | int ls_code; | 399 | int ls_code; |
458 | int status; | 400 | int status; |
459 | }; | 401 | }; |
460 | 402 | ||
403 | struct zfcp_wka_port { | ||
404 | struct zfcp_adapter *adapter; | ||
405 | wait_queue_head_t completion_wq; | ||
406 | enum zfcp_wka_status status; | ||
407 | atomic_t refcount; | ||
408 | u32 d_id; | ||
409 | u32 handle; | ||
410 | struct mutex mutex; | ||
411 | struct delayed_work work; | ||
412 | }; | ||
413 | |||
461 | struct zfcp_qdio_queue { | 414 | struct zfcp_qdio_queue { |
462 | struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */ | 415 | struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; |
463 | u8 first; /* index of next free bfr | 416 | u8 first; /* index of next free bfr in queue */ |
464 | in queue (free_count>0) */ | 417 | atomic_t count; /* number of free buffers in queue */ |
465 | atomic_t count; /* number of free buffers | ||
466 | in queue */ | ||
467 | spinlock_t lock; /* lock for operations on queue */ | ||
468 | int pci_batch; /* SBALs since PCI indication | ||
469 | was last set */ | ||
470 | }; | 418 | }; |
471 | 419 | ||
472 | struct zfcp_erp_action { | 420 | struct zfcp_erp_action { |
@@ -475,7 +423,7 @@ struct zfcp_erp_action { | |||
475 | struct zfcp_adapter *adapter; /* device which should be recovered */ | 423 | struct zfcp_adapter *adapter; /* device which should be recovered */ |
476 | struct zfcp_port *port; | 424 | struct zfcp_port *port; |
477 | struct zfcp_unit *unit; | 425 | struct zfcp_unit *unit; |
478 | volatile u32 status; /* recovery status */ | 426 | u32 status; /* recovery status */ |
479 | u32 step; /* active step of this erp action */ | 427 | u32 step; /* active step of this erp action */ |
480 | struct zfcp_fsf_req *fsf_req; /* fsf request currently pending | 428 | struct zfcp_fsf_req *fsf_req; /* fsf request currently pending |
481 | for this action */ | 429 | for this action */ |
@@ -506,8 +454,8 @@ struct zfcp_adapter { | |||
506 | atomic_t refcount; /* reference count */ | 454 | atomic_t refcount; /* reference count */ |
507 | wait_queue_head_t remove_wq; /* can be used to wait for | 455 | wait_queue_head_t remove_wq; /* can be used to wait for |
508 | refcount drop to zero */ | 456 | refcount drop to zero */ |
509 | wwn_t peer_wwnn; /* P2P peer WWNN */ | 457 | u64 peer_wwnn; /* P2P peer WWNN */ |
510 | wwn_t peer_wwpn; /* P2P peer WWPN */ | 458 | u64 peer_wwpn; /* P2P peer WWPN */ |
511 | u32 peer_d_id; /* P2P peer D_ID */ | 459 | u32 peer_d_id; /* P2P peer D_ID */ |
512 | struct ccw_device *ccw_device; /* S/390 ccw device */ | 460 | struct ccw_device *ccw_device; /* S/390 ccw device */ |
513 | u32 hydra_version; /* Hydra version */ | 461 | u32 hydra_version; /* Hydra version */ |
@@ -518,13 +466,13 @@ struct zfcp_adapter { | |||
518 | u16 timer_ticks; /* time int for a tick */ | 466 | u16 timer_ticks; /* time int for a tick */ |
519 | struct Scsi_Host *scsi_host; /* Pointer to mid-layer */ | 467 | struct Scsi_Host *scsi_host; /* Pointer to mid-layer */ |
520 | struct list_head port_list_head; /* remote port list */ | 468 | struct list_head port_list_head; /* remote port list */ |
521 | struct list_head port_remove_lh; /* head of ports to be | ||
522 | removed */ | ||
523 | u32 ports; /* number of remote ports */ | ||
524 | unsigned long req_no; /* unique FSF req number */ | 469 | unsigned long req_no; /* unique FSF req number */ |
525 | struct list_head *req_list; /* list of pending reqs */ | 470 | struct list_head *req_list; /* list of pending reqs */ |
526 | spinlock_t req_list_lock; /* request list lock */ | 471 | spinlock_t req_list_lock; /* request list lock */ |
527 | struct zfcp_qdio_queue req_q; /* request queue */ | 472 | struct zfcp_qdio_queue req_q; /* request queue */ |
473 | spinlock_t req_q_lock; /* for operations on queue */ | ||
474 | int req_q_pci_batch; /* SBALs since PCI indication | ||
475 | was last set */ | ||
528 | u32 fsf_req_seq_no; /* FSF cmnd seq number */ | 476 | u32 fsf_req_seq_no; /* FSF cmnd seq number */ |
529 | wait_queue_head_t request_wq; /* can be used to wait for | 477 | wait_queue_head_t request_wq; /* can be used to wait for |
530 | more avaliable SBALs */ | 478 | more avaliable SBALs */ |
@@ -548,7 +496,7 @@ struct zfcp_adapter { | |||
548 | actions */ | 496 | actions */ |
549 | u32 erp_low_mem_count; /* nr of erp actions waiting | 497 | u32 erp_low_mem_count; /* nr of erp actions waiting |
550 | for memory */ | 498 | for memory */ |
551 | struct zfcp_port *nameserver_port; /* adapter's nameserver */ | 499 | struct zfcp_wka_port nsp; /* adapter's nameserver */ |
552 | debug_info_t *rec_dbf; | 500 | debug_info_t *rec_dbf; |
553 | debug_info_t *hba_dbf; | 501 | debug_info_t *hba_dbf; |
554 | debug_info_t *san_dbf; /* debug feature areas */ | 502 | debug_info_t *san_dbf; /* debug feature areas */ |
@@ -563,11 +511,11 @@ struct zfcp_adapter { | |||
563 | struct zfcp_scsi_dbf_record scsi_dbf_buf; | 511 | struct zfcp_scsi_dbf_record scsi_dbf_buf; |
564 | struct zfcp_adapter_mempool pool; /* Adapter memory pools */ | 512 | struct zfcp_adapter_mempool pool; /* Adapter memory pools */ |
565 | struct qdio_initialize qdio_init_data; /* for qdio_establish */ | 513 | struct qdio_initialize qdio_init_data; /* for qdio_establish */ |
566 | struct device generic_services; /* directory for WKA ports */ | ||
567 | struct fc_host_statistics *fc_stats; | 514 | struct fc_host_statistics *fc_stats; |
568 | struct fsf_qtcb_bottom_port *stats_reset_data; | 515 | struct fsf_qtcb_bottom_port *stats_reset_data; |
569 | unsigned long stats_reset; | 516 | unsigned long stats_reset; |
570 | struct work_struct scan_work; | 517 | struct work_struct scan_work; |
518 | atomic_t qdio_outb_full; /* queue full incidents */ | ||
571 | }; | 519 | }; |
572 | 520 | ||
573 | struct zfcp_port { | 521 | struct zfcp_port { |
@@ -579,18 +527,16 @@ struct zfcp_port { | |||
579 | refcount drop to zero */ | 527 | refcount drop to zero */ |
580 | struct zfcp_adapter *adapter; /* adapter used to access port */ | 528 | struct zfcp_adapter *adapter; /* adapter used to access port */ |
581 | struct list_head unit_list_head; /* head of logical unit list */ | 529 | struct list_head unit_list_head; /* head of logical unit list */ |
582 | struct list_head unit_remove_lh; /* head of luns to be removed | ||
583 | list */ | ||
584 | u32 units; /* # of logical units in list */ | ||
585 | atomic_t status; /* status of this remote port */ | 530 | atomic_t status; /* status of this remote port */ |
586 | wwn_t wwnn; /* WWNN if known */ | 531 | u64 wwnn; /* WWNN if known */ |
587 | wwn_t wwpn; /* WWPN */ | 532 | u64 wwpn; /* WWPN */ |
588 | u32 d_id; /* D_ID */ | 533 | u32 d_id; /* D_ID */ |
589 | u32 handle; /* handle assigned by FSF */ | 534 | u32 handle; /* handle assigned by FSF */ |
590 | struct zfcp_erp_action erp_action; /* pending error recovery */ | 535 | struct zfcp_erp_action erp_action; /* pending error recovery */ |
591 | atomic_t erp_counter; | 536 | atomic_t erp_counter; |
592 | u32 maxframe_size; | 537 | u32 maxframe_size; |
593 | u32 supported_classes; | 538 | u32 supported_classes; |
539 | struct work_struct gid_pn_work; | ||
594 | }; | 540 | }; |
595 | 541 | ||
596 | struct zfcp_unit { | 542 | struct zfcp_unit { |
@@ -601,8 +547,7 @@ struct zfcp_unit { | |||
601 | refcount drop to zero */ | 547 | refcount drop to zero */ |
602 | struct zfcp_port *port; /* remote port of unit */ | 548 | struct zfcp_port *port; /* remote port of unit */ |
603 | atomic_t status; /* status of this logical unit */ | 549 | atomic_t status; /* status of this logical unit */ |
604 | unsigned int scsi_lun; /* own SCSI LUN */ | 550 | u64 fcp_lun; /* own FCP_LUN */ |
605 | fcp_lun_t fcp_lun; /* own FCP_LUN */ | ||
606 | u32 handle; /* handle assigned by FSF */ | 551 | u32 handle; /* handle assigned by FSF */ |
607 | struct scsi_device *device; /* scsi device struct pointer */ | 552 | struct scsi_device *device; /* scsi device struct pointer */ |
608 | struct zfcp_erp_action erp_action; /* pending error recovery */ | 553 | struct zfcp_erp_action erp_action; /* pending error recovery */ |
@@ -625,7 +570,7 @@ struct zfcp_fsf_req { | |||
625 | u8 sbal_response; /* SBAL used in interrupt */ | 570 | u8 sbal_response; /* SBAL used in interrupt */ |
626 | wait_queue_head_t completion_wq; /* can be used by a routine | 571 | wait_queue_head_t completion_wq; /* can be used by a routine |
627 | to wait for completion */ | 572 | to wait for completion */ |
628 | volatile u32 status; /* status of this request */ | 573 | u32 status; /* status of this request */ |
629 | u32 fsf_command; /* FSF Command copy */ | 574 | u32 fsf_command; /* FSF Command copy */ |
630 | struct fsf_qtcb *qtcb; /* address of associated QTCB */ | 575 | struct fsf_qtcb *qtcb; /* address of associated QTCB */ |
631 | u32 seq_no; /* Sequence number of request */ | 576 | u32 seq_no; /* Sequence number of request */ |
@@ -644,11 +589,7 @@ struct zfcp_fsf_req { | |||
644 | struct zfcp_data { | 589 | struct zfcp_data { |
645 | struct scsi_host_template scsi_host_template; | 590 | struct scsi_host_template scsi_host_template; |
646 | struct scsi_transport_template *scsi_transport_template; | 591 | struct scsi_transport_template *scsi_transport_template; |
647 | atomic_t status; /* Module status flags */ | ||
648 | struct list_head adapter_list_head; /* head of adapter list */ | 592 | struct list_head adapter_list_head; /* head of adapter list */ |
649 | struct list_head adapter_remove_lh; /* head of adapters to be | ||
650 | removed */ | ||
651 | u32 adapters; /* # of adapters in list */ | ||
652 | rwlock_t config_lock; /* serialises changes | 593 | rwlock_t config_lock; /* serialises changes |
653 | to adapter/port/unit | 594 | to adapter/port/unit |
654 | lists */ | 595 | lists */ |
@@ -656,11 +597,12 @@ struct zfcp_data { | |||
656 | changes */ | 597 | changes */ |
657 | atomic_t loglevel; /* current loglevel */ | 598 | atomic_t loglevel; /* current loglevel */ |
658 | char init_busid[BUS_ID_SIZE]; | 599 | char init_busid[BUS_ID_SIZE]; |
659 | wwn_t init_wwpn; | 600 | u64 init_wwpn; |
660 | fcp_lun_t init_fcp_lun; | 601 | u64 init_fcp_lun; |
661 | struct kmem_cache *fsf_req_qtcb_cache; | 602 | struct kmem_cache *fsf_req_qtcb_cache; |
662 | struct kmem_cache *sr_buffer_cache; | 603 | struct kmem_cache *sr_buffer_cache; |
663 | struct kmem_cache *gid_pn_cache; | 604 | struct kmem_cache *gid_pn_cache; |
605 | struct workqueue_struct *work_queue; | ||
664 | }; | 606 | }; |
665 | 607 | ||
666 | /* struct used by memory pools for fsf_requests */ | 608 | /* struct used by memory pools for fsf_requests */ |
@@ -677,14 +619,7 @@ struct zfcp_fsf_req_qtcb { | |||
677 | #define ZFCP_SET 0x00000100 | 619 | #define ZFCP_SET 0x00000100 |
678 | #define ZFCP_CLEAR 0x00000200 | 620 | #define ZFCP_CLEAR 0x00000200 |
679 | 621 | ||
680 | #ifndef atomic_test_mask | ||
681 | #define atomic_test_mask(mask, target) \ | ||
682 | ((atomic_read(target) & mask) == mask) | ||
683 | #endif | ||
684 | |||
685 | #define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id) | 622 | #define zfcp_get_busid_by_adapter(adapter) (adapter->ccw_device->dev.bus_id) |
686 | #define zfcp_get_busid_by_port(port) (zfcp_get_busid_by_adapter(port->adapter)) | ||
687 | #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) | ||
688 | 623 | ||
689 | /* | 624 | /* |
690 | * Helper functions for request ID management. | 625 | * Helper functions for request ID management. |
@@ -745,12 +680,6 @@ zfcp_unit_put(struct zfcp_unit *unit) | |||
745 | } | 680 | } |
746 | 681 | ||
747 | static inline void | 682 | static inline void |
748 | zfcp_unit_wait(struct zfcp_unit *unit) | ||
749 | { | ||
750 | wait_event(unit->remove_wq, atomic_read(&unit->refcount) == 0); | ||
751 | } | ||
752 | |||
753 | static inline void | ||
754 | zfcp_port_get(struct zfcp_port *port) | 683 | zfcp_port_get(struct zfcp_port *port) |
755 | { | 684 | { |
756 | atomic_inc(&port->refcount); | 685 | atomic_inc(&port->refcount); |
@@ -764,12 +693,6 @@ zfcp_port_put(struct zfcp_port *port) | |||
764 | } | 693 | } |
765 | 694 | ||
766 | static inline void | 695 | static inline void |
767 | zfcp_port_wait(struct zfcp_port *port) | ||
768 | { | ||
769 | wait_event(port->remove_wq, atomic_read(&port->refcount) == 0); | ||
770 | } | ||
771 | |||
772 | static inline void | ||
773 | zfcp_adapter_get(struct zfcp_adapter *adapter) | 696 | zfcp_adapter_get(struct zfcp_adapter *adapter) |
774 | { | 697 | { |
775 | atomic_inc(&adapter->refcount); | 698 | atomic_inc(&adapter->refcount); |
@@ -782,10 +705,4 @@ zfcp_adapter_put(struct zfcp_adapter *adapter) | |||
782 | wake_up(&adapter->remove_wq); | 705 | wake_up(&adapter->remove_wq); |
783 | } | 706 | } |
784 | 707 | ||
785 | static inline void | ||
786 | zfcp_adapter_wait(struct zfcp_adapter *adapter) | ||
787 | { | ||
788 | wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); | ||
789 | } | ||
790 | |||
791 | #endif /* ZFCP_DEF_H */ | 708 | #endif /* ZFCP_DEF_H */ |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 643ac4bba5b5..782313131870 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -23,7 +23,6 @@ enum zfcp_erp_steps { | |||
23 | ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001, | 23 | ZFCP_ERP_STEP_FSF_XCONFIG = 0x0001, |
24 | ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, | 24 | ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, |
25 | ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, | 25 | ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, |
26 | ZFCP_ERP_STEP_NAMESERVER_OPEN = 0x0200, | ||
27 | ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400, | 26 | ZFCP_ERP_STEP_NAMESERVER_LOOKUP = 0x0400, |
28 | ZFCP_ERP_STEP_PORT_OPENING = 0x0800, | 27 | ZFCP_ERP_STEP_PORT_OPENING = 0x0800, |
29 | ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, | 28 | ZFCP_ERP_STEP_UNIT_CLOSING = 0x1000, |
@@ -532,8 +531,7 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, | |||
532 | struct zfcp_port *port; | 531 | struct zfcp_port *port; |
533 | 532 | ||
534 | list_for_each_entry(port, &adapter->port_list_head, list) | 533 | list_for_each_entry(port, &adapter->port_list_head, list) |
535 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA)) | 534 | _zfcp_erp_port_reopen(port, clear, id, ref); |
536 | _zfcp_erp_port_reopen(port, clear, id, ref); | ||
537 | } | 535 | } |
538 | 536 | ||
539 | static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id, | 537 | static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id, |
@@ -669,8 +667,6 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act) | |||
669 | int ret; | 667 | int ret; |
670 | struct zfcp_adapter *adapter = act->adapter; | 668 | struct zfcp_adapter *adapter = act->adapter; |
671 | 669 | ||
672 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | ||
673 | |||
674 | write_lock_irq(&adapter->erp_lock); | 670 | write_lock_irq(&adapter->erp_lock); |
675 | zfcp_erp_action_to_running(act); | 671 | zfcp_erp_action_to_running(act); |
676 | write_unlock_irq(&adapter->erp_lock); | 672 | write_unlock_irq(&adapter->erp_lock); |
@@ -741,8 +737,7 @@ static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act, | |||
741 | ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); | 737 | ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); |
742 | failed_qdio: | 738 | failed_qdio: |
743 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | | 739 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | |
744 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | | 740 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, |
745 | ZFCP_STATUS_ADAPTER_XPORT_OK, | ||
746 | &act->adapter->status); | 741 | &act->adapter->status); |
747 | return retval; | 742 | return retval; |
748 | } | 743 | } |
@@ -751,15 +746,11 @@ static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act) | |||
751 | { | 746 | { |
752 | int retval; | 747 | int retval; |
753 | 748 | ||
754 | atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status); | ||
755 | zfcp_erp_adapter_strategy_generic(act, 1); /* close */ | 749 | zfcp_erp_adapter_strategy_generic(act, 1); /* close */ |
756 | atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &act->adapter->status); | ||
757 | if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY) | 750 | if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY) |
758 | return ZFCP_ERP_EXIT; | 751 | return ZFCP_ERP_EXIT; |
759 | 752 | ||
760 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status); | ||
761 | retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */ | 753 | retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */ |
762 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &act->adapter->status); | ||
763 | 754 | ||
764 | if (retval == ZFCP_ERP_FAILED) | 755 | if (retval == ZFCP_ERP_FAILED) |
765 | ssleep(8); | 756 | ssleep(8); |
@@ -783,10 +774,7 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act) | |||
783 | 774 | ||
784 | static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) | 775 | static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) |
785 | { | 776 | { |
786 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | | 777 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | |
787 | ZFCP_STATUS_COMMON_CLOSING | | ||
788 | ZFCP_STATUS_COMMON_ACCESS_DENIED | | ||
789 | ZFCP_STATUS_PORT_DID_DID | | ||
790 | ZFCP_STATUS_PORT_PHYS_CLOSING | | 778 | ZFCP_STATUS_PORT_PHYS_CLOSING | |
791 | ZFCP_STATUS_PORT_INVALID_WWPN, | 779 | ZFCP_STATUS_PORT_INVALID_WWPN, |
792 | &port->status); | 780 | &port->status); |
@@ -839,73 +827,12 @@ static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) | |||
839 | return ZFCP_ERP_CONTINUES; | 827 | return ZFCP_ERP_CONTINUES; |
840 | } | 828 | } |
841 | 829 | ||
842 | static void zfcp_erp_port_strategy_open_ns_wake(struct zfcp_erp_action *ns_act) | ||
843 | { | ||
844 | unsigned long flags; | ||
845 | struct zfcp_adapter *adapter = ns_act->adapter; | ||
846 | struct zfcp_erp_action *act, *tmp; | ||
847 | int status; | ||
848 | |||
849 | read_lock_irqsave(&adapter->erp_lock, flags); | ||
850 | list_for_each_entry_safe(act, tmp, &adapter->erp_running_head, list) { | ||
851 | if (act->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) { | ||
852 | status = atomic_read(&adapter->nameserver_port->status); | ||
853 | if (status & ZFCP_STATUS_COMMON_ERP_FAILED) | ||
854 | zfcp_erp_port_failed(act->port, 27, NULL); | ||
855 | zfcp_erp_action_ready(act); | ||
856 | } | ||
857 | } | ||
858 | read_unlock_irqrestore(&adapter->erp_lock, flags); | ||
859 | } | ||
860 | |||
861 | static int zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *act) | ||
862 | { | ||
863 | int retval; | ||
864 | |||
865 | switch (act->step) { | ||
866 | case ZFCP_ERP_STEP_UNINITIALIZED: | ||
867 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: | ||
868 | case ZFCP_ERP_STEP_PORT_CLOSING: | ||
869 | return zfcp_erp_port_strategy_open_port(act); | ||
870 | |||
871 | case ZFCP_ERP_STEP_PORT_OPENING: | ||
872 | if (atomic_read(&act->port->status) & ZFCP_STATUS_COMMON_OPEN) | ||
873 | retval = ZFCP_ERP_SUCCEEDED; | ||
874 | else | ||
875 | retval = ZFCP_ERP_FAILED; | ||
876 | /* this is needed anyway */ | ||
877 | zfcp_erp_port_strategy_open_ns_wake(act); | ||
878 | return retval; | ||
879 | |||
880 | default: | ||
881 | return ZFCP_ERP_FAILED; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | static int zfcp_erp_port_strategy_open_lookup(struct zfcp_erp_action *act) | ||
886 | { | ||
887 | int retval; | ||
888 | |||
889 | retval = zfcp_fc_ns_gid_pn_request(act); | ||
890 | if (retval == -ENOMEM) | ||
891 | return ZFCP_ERP_NOMEM; | ||
892 | act->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; | ||
893 | if (retval) | ||
894 | return ZFCP_ERP_FAILED; | ||
895 | return ZFCP_ERP_CONTINUES; | ||
896 | } | ||
897 | |||
898 | static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) | 830 | static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) |
899 | { | 831 | { |
900 | struct zfcp_adapter *adapter = act->adapter; | 832 | struct zfcp_adapter *adapter = act->adapter; |
901 | struct zfcp_port *port = act->port; | 833 | struct zfcp_port *port = act->port; |
902 | 834 | ||
903 | if (port->wwpn != adapter->peer_wwpn) { | 835 | if (port->wwpn != adapter->peer_wwpn) { |
904 | dev_err(&adapter->ccw_device->dev, | ||
905 | "Failed to open port 0x%016Lx, " | ||
906 | "Peer WWPN 0x%016Lx does not " | ||
907 | "match.\n", port->wwpn, | ||
908 | adapter->peer_wwpn); | ||
909 | zfcp_erp_port_failed(port, 25, NULL); | 836 | zfcp_erp_port_failed(port, 25, NULL); |
910 | return ZFCP_ERP_FAILED; | 837 | return ZFCP_ERP_FAILED; |
911 | } | 838 | } |
@@ -914,11 +841,25 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act) | |||
914 | return zfcp_erp_port_strategy_open_port(act); | 841 | return zfcp_erp_port_strategy_open_port(act); |
915 | } | 842 | } |
916 | 843 | ||
844 | void zfcp_erp_port_strategy_open_lookup(struct work_struct *work) | ||
845 | { | ||
846 | int retval; | ||
847 | struct zfcp_port *port = container_of(work, struct zfcp_port, | ||
848 | gid_pn_work); | ||
849 | |||
850 | retval = zfcp_fc_ns_gid_pn(&port->erp_action); | ||
851 | if (retval == -ENOMEM) | ||
852 | zfcp_erp_notify(&port->erp_action, ZFCP_ERP_NOMEM); | ||
853 | port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; | ||
854 | if (retval) | ||
855 | zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED); | ||
856 | |||
857 | } | ||
858 | |||
917 | static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | 859 | static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) |
918 | { | 860 | { |
919 | struct zfcp_adapter *adapter = act->adapter; | 861 | struct zfcp_adapter *adapter = act->adapter; |
920 | struct zfcp_port *port = act->port; | 862 | struct zfcp_port *port = act->port; |
921 | struct zfcp_port *ns_port = adapter->nameserver_port; | ||
922 | int p_status = atomic_read(&port->status); | 863 | int p_status = atomic_read(&port->status); |
923 | 864 | ||
924 | switch (act->step) { | 865 | switch (act->step) { |
@@ -927,28 +868,10 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
927 | case ZFCP_ERP_STEP_PORT_CLOSING: | 868 | case ZFCP_ERP_STEP_PORT_CLOSING: |
928 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) | 869 | if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) |
929 | return zfcp_erp_open_ptp_port(act); | 870 | return zfcp_erp_open_ptp_port(act); |
930 | if (!ns_port) { | 871 | if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { |
931 | dev_err(&adapter->ccw_device->dev, | 872 | queue_work(zfcp_data.work_queue, &port->gid_pn_work); |
932 | "Nameserver port unavailable.\n"); | 873 | return ZFCP_ERP_CONTINUES; |
933 | return ZFCP_ERP_FAILED; | ||
934 | } | ||
935 | if (!(atomic_read(&ns_port->status) & | ||
936 | ZFCP_STATUS_COMMON_UNBLOCKED)) { | ||
937 | /* nameserver port may live again */ | ||
938 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, | ||
939 | &ns_port->status); | ||
940 | if (zfcp_erp_port_reopen(ns_port, 0, 77, act) >= 0) { | ||
941 | act->step = ZFCP_ERP_STEP_NAMESERVER_OPEN; | ||
942 | return ZFCP_ERP_CONTINUES; | ||
943 | } | ||
944 | return ZFCP_ERP_FAILED; | ||
945 | } | 874 | } |
946 | /* else nameserver port is already open, fall through */ | ||
947 | case ZFCP_ERP_STEP_NAMESERVER_OPEN: | ||
948 | if (!(atomic_read(&ns_port->status) & ZFCP_STATUS_COMMON_OPEN)) | ||
949 | return ZFCP_ERP_FAILED; | ||
950 | return zfcp_erp_port_strategy_open_lookup(act); | ||
951 | |||
952 | case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: | 875 | case ZFCP_ERP_STEP_NAMESERVER_LOOKUP: |
953 | if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { | 876 | if (!(p_status & ZFCP_STATUS_PORT_DID_DID)) { |
954 | if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) { | 877 | if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) { |
@@ -961,25 +884,26 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) | |||
961 | 884 | ||
962 | case ZFCP_ERP_STEP_PORT_OPENING: | 885 | case ZFCP_ERP_STEP_PORT_OPENING: |
963 | /* D_ID might have changed during open */ | 886 | /* D_ID might have changed during open */ |
964 | if ((p_status & ZFCP_STATUS_COMMON_OPEN) && | 887 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { |
965 | (p_status & ZFCP_STATUS_PORT_DID_DID)) | 888 | if (p_status & ZFCP_STATUS_PORT_DID_DID) |
966 | return ZFCP_ERP_SUCCEEDED; | 889 | return ZFCP_ERP_SUCCEEDED; |
890 | else { | ||
891 | act->step = ZFCP_ERP_STEP_PORT_CLOSING; | ||
892 | return ZFCP_ERP_CONTINUES; | ||
893 | } | ||
967 | /* fall through otherwise */ | 894 | /* fall through otherwise */ |
895 | } | ||
968 | } | 896 | } |
969 | return ZFCP_ERP_FAILED; | 897 | return ZFCP_ERP_FAILED; |
970 | } | 898 | } |
971 | 899 | ||
972 | static int zfcp_erp_port_strategy_open(struct zfcp_erp_action *act) | ||
973 | { | ||
974 | if (atomic_read(&act->port->status) & (ZFCP_STATUS_PORT_WKA)) | ||
975 | return zfcp_erp_port_strategy_open_nameserver(act); | ||
976 | return zfcp_erp_port_strategy_open_common(act); | ||
977 | } | ||
978 | |||
979 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | 900 | static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) |
980 | { | 901 | { |
981 | struct zfcp_port *port = erp_action->port; | 902 | struct zfcp_port *port = erp_action->port; |
982 | 903 | ||
904 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_NOESC) | ||
905 | goto close_init_done; | ||
906 | |||
983 | switch (erp_action->step) { | 907 | switch (erp_action->step) { |
984 | case ZFCP_ERP_STEP_UNINITIALIZED: | 908 | case ZFCP_ERP_STEP_UNINITIALIZED: |
985 | zfcp_erp_port_strategy_clearstati(port); | 909 | zfcp_erp_port_strategy_clearstati(port); |
@@ -992,19 +916,17 @@ static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | |||
992 | return ZFCP_ERP_FAILED; | 916 | return ZFCP_ERP_FAILED; |
993 | break; | 917 | break; |
994 | } | 918 | } |
919 | |||
920 | close_init_done: | ||
995 | if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) | 921 | if (erp_action->status & ZFCP_STATUS_ERP_CLOSE_ONLY) |
996 | return ZFCP_ERP_EXIT; | 922 | return ZFCP_ERP_EXIT; |
997 | else | ||
998 | return zfcp_erp_port_strategy_open(erp_action); | ||
999 | 923 | ||
1000 | return ZFCP_ERP_FAILED; | 924 | return zfcp_erp_port_strategy_open_common(erp_action); |
1001 | } | 925 | } |
1002 | 926 | ||
1003 | static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) | 927 | static void zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) |
1004 | { | 928 | { |
1005 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | | 929 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | |
1006 | ZFCP_STATUS_COMMON_CLOSING | | ||
1007 | ZFCP_STATUS_COMMON_ACCESS_DENIED | | ||
1008 | ZFCP_STATUS_UNIT_SHARED | | 930 | ZFCP_STATUS_UNIT_SHARED | |
1009 | ZFCP_STATUS_UNIT_READONLY, | 931 | ZFCP_STATUS_UNIT_READONLY, |
1010 | &unit->status); | 932 | &unit->status); |
@@ -1065,8 +987,14 @@ static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) | |||
1065 | break; | 987 | break; |
1066 | case ZFCP_ERP_FAILED : | 988 | case ZFCP_ERP_FAILED : |
1067 | atomic_inc(&unit->erp_counter); | 989 | atomic_inc(&unit->erp_counter); |
1068 | if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) | 990 | if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) { |
991 | dev_err(&unit->port->adapter->ccw_device->dev, | ||
992 | "ERP failed for unit 0x%016Lx on " | ||
993 | "port 0x%016Lx\n", | ||
994 | (unsigned long long)unit->fcp_lun, | ||
995 | (unsigned long long)unit->port->wwpn); | ||
1069 | zfcp_erp_unit_failed(unit, 21, NULL); | 996 | zfcp_erp_unit_failed(unit, 21, NULL); |
997 | } | ||
1070 | break; | 998 | break; |
1071 | } | 999 | } |
1072 | 1000 | ||
@@ -1091,8 +1019,12 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) | |||
1091 | result = ZFCP_ERP_EXIT; | 1019 | result = ZFCP_ERP_EXIT; |
1092 | } | 1020 | } |
1093 | atomic_inc(&port->erp_counter); | 1021 | atomic_inc(&port->erp_counter); |
1094 | if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) | 1022 | if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) { |
1023 | dev_err(&port->adapter->ccw_device->dev, | ||
1024 | "ERP failed for remote port 0x%016Lx\n", | ||
1025 | (unsigned long long)port->wwpn); | ||
1095 | zfcp_erp_port_failed(port, 22, NULL); | 1026 | zfcp_erp_port_failed(port, 22, NULL); |
1027 | } | ||
1096 | break; | 1028 | break; |
1097 | } | 1029 | } |
1098 | 1030 | ||
@@ -1114,8 +1046,12 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, | |||
1114 | 1046 | ||
1115 | case ZFCP_ERP_FAILED : | 1047 | case ZFCP_ERP_FAILED : |
1116 | atomic_inc(&adapter->erp_counter); | 1048 | atomic_inc(&adapter->erp_counter); |
1117 | if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS) | 1049 | if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS) { |
1050 | dev_err(&adapter->ccw_device->dev, | ||
1051 | "ERP cannot recover an error " | ||
1052 | "on the FCP device\n"); | ||
1118 | zfcp_erp_adapter_failed(adapter, 23, NULL); | 1053 | zfcp_erp_adapter_failed(adapter, 23, NULL); |
1054 | } | ||
1119 | break; | 1055 | break; |
1120 | } | 1056 | } |
1121 | 1057 | ||
@@ -1250,9 +1186,10 @@ static void zfcp_erp_scsi_scan(struct work_struct *work) | |||
1250 | struct zfcp_unit *unit = p->unit; | 1186 | struct zfcp_unit *unit = p->unit; |
1251 | struct fc_rport *rport = unit->port->rport; | 1187 | struct fc_rport *rport = unit->port->rport; |
1252 | scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, | 1188 | scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, |
1253 | unit->scsi_lun, 0); | 1189 | scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0); |
1254 | atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); | 1190 | atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); |
1255 | zfcp_unit_put(unit); | 1191 | zfcp_unit_put(unit); |
1192 | wake_up(&unit->port->adapter->erp_done_wqh); | ||
1256 | kfree(p); | 1193 | kfree(p); |
1257 | } | 1194 | } |
1258 | 1195 | ||
@@ -1263,9 +1200,9 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit) | |||
1263 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 1200 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
1264 | if (!p) { | 1201 | if (!p) { |
1265 | dev_err(&unit->port->adapter->ccw_device->dev, | 1202 | dev_err(&unit->port->adapter->ccw_device->dev, |
1266 | "Out of resources. Could not register unit " | 1203 | "Registering unit 0x%016Lx on port 0x%016Lx failed\n", |
1267 | "0x%016Lx on port 0x%016Lx with SCSI stack.\n", | 1204 | (unsigned long long)unit->fcp_lun, |
1268 | unit->fcp_lun, unit->port->wwpn); | 1205 | (unsigned long long)unit->port->wwpn); |
1269 | return; | 1206 | return; |
1270 | } | 1207 | } |
1271 | 1208 | ||
@@ -1273,7 +1210,7 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit) | |||
1273 | atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); | 1210 | atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); |
1274 | INIT_WORK(&p->work, zfcp_erp_scsi_scan); | 1211 | INIT_WORK(&p->work, zfcp_erp_scsi_scan); |
1275 | p->unit = unit; | 1212 | p->unit = unit; |
1276 | schedule_work(&p->work); | 1213 | queue_work(zfcp_data.work_queue, &p->work); |
1277 | } | 1214 | } |
1278 | 1215 | ||
1279 | static void zfcp_erp_rport_register(struct zfcp_port *port) | 1216 | static void zfcp_erp_rport_register(struct zfcp_port *port) |
@@ -1286,8 +1223,8 @@ static void zfcp_erp_rport_register(struct zfcp_port *port) | |||
1286 | port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids); | 1223 | port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids); |
1287 | if (!port->rport) { | 1224 | if (!port->rport) { |
1288 | dev_err(&port->adapter->ccw_device->dev, | 1225 | dev_err(&port->adapter->ccw_device->dev, |
1289 | "Failed registration of rport " | 1226 | "Registering port 0x%016Lx failed\n", |
1290 | "0x%016Lx.\n", port->wwpn); | 1227 | (unsigned long long)port->wwpn); |
1291 | return; | 1228 | return; |
1292 | } | 1229 | } |
1293 | 1230 | ||
@@ -1299,12 +1236,12 @@ static void zfcp_erp_rport_register(struct zfcp_port *port) | |||
1299 | static void zfcp_erp_rports_del(struct zfcp_adapter *adapter) | 1236 | static void zfcp_erp_rports_del(struct zfcp_adapter *adapter) |
1300 | { | 1237 | { |
1301 | struct zfcp_port *port; | 1238 | struct zfcp_port *port; |
1302 | list_for_each_entry(port, &adapter->port_list_head, list) | 1239 | list_for_each_entry(port, &adapter->port_list_head, list) { |
1303 | if (port->rport && !(atomic_read(&port->status) & | 1240 | if (!port->rport) |
1304 | ZFCP_STATUS_PORT_WKA)) { | 1241 | continue; |
1305 | fc_remote_port_delete(port->rport); | 1242 | fc_remote_port_delete(port->rport); |
1306 | port->rport = NULL; | 1243 | port->rport = NULL; |
1307 | } | 1244 | } |
1308 | } | 1245 | } |
1309 | 1246 | ||
1310 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) | 1247 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) |
@@ -1459,9 +1396,9 @@ static int zfcp_erp_thread(void *data) | |||
1459 | zfcp_erp_wakeup(adapter); | 1396 | zfcp_erp_wakeup(adapter); |
1460 | } | 1397 | } |
1461 | 1398 | ||
1462 | zfcp_rec_dbf_event_thread(4, adapter); | 1399 | zfcp_rec_dbf_event_thread_lock(4, adapter); |
1463 | down_interruptible(&adapter->erp_ready_sem); | 1400 | down_interruptible(&adapter->erp_ready_sem); |
1464 | zfcp_rec_dbf_event_thread(5, adapter); | 1401 | zfcp_rec_dbf_event_thread_lock(5, adapter); |
1465 | } | 1402 | } |
1466 | 1403 | ||
1467 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); | 1404 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); |
@@ -1484,7 +1421,7 @@ int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) | |||
1484 | retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); | 1421 | retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD); |
1485 | if (retval < 0) { | 1422 | if (retval < 0) { |
1486 | dev_err(&adapter->ccw_device->dev, | 1423 | dev_err(&adapter->ccw_device->dev, |
1487 | "Creation of ERP thread failed.\n"); | 1424 | "Creating an ERP thread for the FCP device failed.\n"); |
1488 | return retval; | 1425 | return retval; |
1489 | } | 1426 | } |
1490 | wait_event(adapter->erp_thread_wqh, | 1427 | wait_event(adapter->erp_thread_wqh, |
@@ -1506,7 +1443,7 @@ void zfcp_erp_thread_kill(struct zfcp_adapter *adapter) | |||
1506 | { | 1443 | { |
1507 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); | 1444 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); |
1508 | up(&adapter->erp_ready_sem); | 1445 | up(&adapter->erp_ready_sem); |
1509 | zfcp_rec_dbf_event_thread_lock(2, adapter); | 1446 | zfcp_rec_dbf_event_thread_lock(3, adapter); |
1510 | 1447 | ||
1511 | wait_event(adapter->erp_thread_wqh, | 1448 | wait_event(adapter->erp_thread_wqh, |
1512 | !(atomic_read(&adapter->status) & | 1449 | !(atomic_read(&adapter->status) & |
@@ -1526,7 +1463,6 @@ void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref) | |||
1526 | { | 1463 | { |
1527 | zfcp_erp_modify_adapter_status(adapter, id, ref, | 1464 | zfcp_erp_modify_adapter_status(adapter, id, ref, |
1528 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); | 1465 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); |
1529 | dev_err(&adapter->ccw_device->dev, "Adapter ERP failed.\n"); | ||
1530 | } | 1466 | } |
1531 | 1467 | ||
1532 | /** | 1468 | /** |
@@ -1539,15 +1475,6 @@ void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref) | |||
1539 | { | 1475 | { |
1540 | zfcp_erp_modify_port_status(port, id, ref, | 1476 | zfcp_erp_modify_port_status(port, id, ref, |
1541 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); | 1477 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); |
1542 | |||
1543 | if (atomic_read(&port->status) & ZFCP_STATUS_PORT_WKA) | ||
1544 | dev_err(&port->adapter->ccw_device->dev, | ||
1545 | "Port ERP failed for WKA port d_id=0x%06x.\n", | ||
1546 | port->d_id); | ||
1547 | else | ||
1548 | dev_err(&port->adapter->ccw_device->dev, | ||
1549 | "Port ERP failed for port wwpn=0x%016Lx.\n", | ||
1550 | port->wwpn); | ||
1551 | } | 1478 | } |
1552 | 1479 | ||
1553 | /** | 1480 | /** |
@@ -1560,10 +1487,6 @@ void zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref) | |||
1560 | { | 1487 | { |
1561 | zfcp_erp_modify_unit_status(unit, id, ref, | 1488 | zfcp_erp_modify_unit_status(unit, id, ref, |
1562 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); | 1489 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); |
1563 | |||
1564 | dev_err(&unit->port->adapter->ccw_device->dev, | ||
1565 | "Unit ERP failed for unit 0x%016Lx on port 0x%016Lx.\n", | ||
1566 | unit->fcp_lun, unit->port->wwpn); | ||
1567 | } | 1490 | } |
1568 | 1491 | ||
1569 | /** | 1492 | /** |
@@ -1754,9 +1677,8 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, | |||
1754 | 1677 | ||
1755 | if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | | 1678 | if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | |
1756 | ZFCP_STATUS_COMMON_ACCESS_BOXED))) { | 1679 | ZFCP_STATUS_COMMON_ACCESS_BOXED))) { |
1757 | if (!(status & ZFCP_STATUS_PORT_WKA)) | 1680 | list_for_each_entry(unit, &port->unit_list_head, list) |
1758 | list_for_each_entry(unit, &port->unit_list_head, list) | 1681 | zfcp_erp_unit_access_changed(unit, id, ref); |
1759 | zfcp_erp_unit_access_changed(unit, id, ref); | ||
1760 | return; | 1682 | return; |
1761 | } | 1683 | } |
1762 | 1684 | ||
@@ -1779,10 +1701,7 @@ void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id, | |||
1779 | return; | 1701 | return; |
1780 | 1702 | ||
1781 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1703 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
1782 | if (adapter->nameserver_port) | ||
1783 | zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref); | ||
1784 | list_for_each_entry(port, &adapter->port_list_head, list) | 1704 | list_for_each_entry(port, &adapter->port_list_head, list) |
1785 | if (port != adapter->nameserver_port) | 1705 | zfcp_erp_port_access_changed(port, id, ref); |
1786 | zfcp_erp_port_access_changed(port, id, ref); | ||
1787 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 1706 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
1788 | } | 1707 | } |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index edfdb21591f3..b5adeda93e1d 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -12,16 +12,14 @@ | |||
12 | #include "zfcp_def.h" | 12 | #include "zfcp_def.h" |
13 | 13 | ||
14 | /* zfcp_aux.c */ | 14 | /* zfcp_aux.c */ |
15 | extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, | 15 | extern struct zfcp_unit *zfcp_get_unit_by_lun(struct zfcp_port *, u64); |
16 | fcp_lun_t); | 16 | extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, u64); |
17 | extern struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *, | ||
18 | wwn_t); | ||
19 | extern int zfcp_adapter_enqueue(struct ccw_device *); | 17 | extern int zfcp_adapter_enqueue(struct ccw_device *); |
20 | extern void zfcp_adapter_dequeue(struct zfcp_adapter *); | 18 | extern void zfcp_adapter_dequeue(struct zfcp_adapter *); |
21 | extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, wwn_t, u32, | 19 | extern struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *, u64, u32, |
22 | u32); | 20 | u32); |
23 | extern void zfcp_port_dequeue(struct zfcp_port *); | 21 | extern void zfcp_port_dequeue(struct zfcp_port *); |
24 | extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, fcp_lun_t); | 22 | extern struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *, u64); |
25 | extern void zfcp_unit_dequeue(struct zfcp_unit *); | 23 | extern void zfcp_unit_dequeue(struct zfcp_unit *); |
26 | extern int zfcp_reqlist_isempty(struct zfcp_adapter *); | 24 | extern int zfcp_reqlist_isempty(struct zfcp_adapter *); |
27 | extern void zfcp_sg_free_table(struct scatterlist *, int); | 25 | extern void zfcp_sg_free_table(struct scatterlist *, int); |
@@ -29,6 +27,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int); | |||
29 | 27 | ||
30 | /* zfcp_ccw.c */ | 28 | /* zfcp_ccw.c */ |
31 | extern int zfcp_ccw_register(void); | 29 | extern int zfcp_ccw_register(void); |
30 | extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *); | ||
32 | 31 | ||
33 | /* zfcp_cfdc.c */ | 32 | /* zfcp_cfdc.c */ |
34 | extern struct miscdevice zfcp_cfdc_misc; | 33 | extern struct miscdevice zfcp_cfdc_misc; |
@@ -50,6 +49,8 @@ extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *, | |||
50 | struct fsf_status_read_buffer *); | 49 | struct fsf_status_read_buffer *); |
51 | extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, unsigned int, int, | 50 | extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, unsigned int, int, |
52 | int); | 51 | int); |
52 | extern void zfcp_hba_dbf_event_berr(struct zfcp_adapter *, | ||
53 | struct zfcp_fsf_req *); | ||
53 | extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *); | 54 | extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *); |
54 | extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *); | 55 | extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *); |
55 | extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *); | 56 | extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *); |
@@ -91,17 +92,21 @@ extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8, void *); | |||
91 | extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *); | 92 | extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *); |
92 | extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *); | 93 | extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *); |
93 | extern void zfcp_erp_timeout_handler(unsigned long); | 94 | extern void zfcp_erp_timeout_handler(unsigned long); |
95 | extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *); | ||
94 | 96 | ||
95 | /* zfcp_fc.c */ | 97 | /* zfcp_fc.c */ |
96 | extern int zfcp_scan_ports(struct zfcp_adapter *); | 98 | extern int zfcp_scan_ports(struct zfcp_adapter *); |
97 | extern void _zfcp_scan_ports_later(struct work_struct *); | 99 | extern void _zfcp_scan_ports_later(struct work_struct *); |
98 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); | 100 | extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *); |
99 | extern int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *); | 101 | extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *); |
100 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); | 102 | extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *); |
101 | extern void zfcp_test_link(struct zfcp_port *); | 103 | extern void zfcp_test_link(struct zfcp_port *); |
104 | extern void zfcp_fc_nameserver_init(struct zfcp_adapter *); | ||
102 | 105 | ||
103 | /* zfcp_fsf.c */ | 106 | /* zfcp_fsf.c */ |
104 | extern int zfcp_fsf_open_port(struct zfcp_erp_action *); | 107 | extern int zfcp_fsf_open_port(struct zfcp_erp_action *); |
108 | extern int zfcp_fsf_open_wka_port(struct zfcp_wka_port *); | ||
109 | extern int zfcp_fsf_close_wka_port(struct zfcp_wka_port *); | ||
105 | extern int zfcp_fsf_close_port(struct zfcp_erp_action *); | 110 | extern int zfcp_fsf_close_port(struct zfcp_erp_action *); |
106 | extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); | 111 | extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *); |
107 | extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); | 112 | extern int zfcp_fsf_open_unit(struct zfcp_erp_action *); |
@@ -135,10 +140,8 @@ extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long, | |||
135 | extern int zfcp_qdio_allocate(struct zfcp_adapter *); | 140 | extern int zfcp_qdio_allocate(struct zfcp_adapter *); |
136 | extern void zfcp_qdio_free(struct zfcp_adapter *); | 141 | extern void zfcp_qdio_free(struct zfcp_adapter *); |
137 | extern int zfcp_qdio_send(struct zfcp_fsf_req *); | 142 | extern int zfcp_qdio_send(struct zfcp_fsf_req *); |
138 | extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_req( | 143 | extern struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *); |
139 | struct zfcp_fsf_req *); | 144 | extern struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *); |
140 | extern volatile struct qdio_buffer_element *zfcp_qdio_sbale_curr( | ||
141 | struct zfcp_fsf_req *); | ||
142 | extern int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *, unsigned long, | 145 | extern int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *, unsigned long, |
143 | struct scatterlist *, int); | 146 | struct scatterlist *, int); |
144 | extern int zfcp_qdio_open(struct zfcp_adapter *); | 147 | extern int zfcp_qdio_open(struct zfcp_adapter *); |
@@ -148,14 +151,12 @@ extern void zfcp_qdio_close(struct zfcp_adapter *); | |||
148 | extern struct zfcp_data zfcp_data; | 151 | extern struct zfcp_data zfcp_data; |
149 | extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); | 152 | extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); |
150 | extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); | 153 | extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); |
151 | extern void zfcp_set_fcp_dl(struct fcp_cmnd_iu *, fcp_dl_t); | ||
152 | extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); | 154 | extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); |
153 | extern struct fc_function_template zfcp_transport_functions; | 155 | extern struct fc_function_template zfcp_transport_functions; |
154 | 156 | ||
155 | /* zfcp_sysfs.c */ | 157 | /* zfcp_sysfs.c */ |
156 | extern struct attribute_group zfcp_sysfs_unit_attrs; | 158 | extern struct attribute_group zfcp_sysfs_unit_attrs; |
157 | extern struct attribute_group zfcp_sysfs_adapter_attrs; | 159 | extern struct attribute_group zfcp_sysfs_adapter_attrs; |
158 | extern struct attribute_group zfcp_sysfs_ns_port_attrs; | ||
159 | extern struct attribute_group zfcp_sysfs_port_attrs; | 160 | extern struct attribute_group zfcp_sysfs_port_attrs; |
160 | extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; | 161 | extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; |
161 | extern struct device_attribute *zfcp_sysfs_shost_attrs[]; | 162 | extern struct device_attribute *zfcp_sysfs_shost_attrs[]; |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 56196c98c07b..1a7c80a77ff5 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -39,6 +39,84 @@ struct zfcp_gpn_ft { | |||
39 | struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; | 39 | struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct zfcp_fc_ns_handler_data { | ||
43 | struct completion done; | ||
44 | void (*handler)(unsigned long); | ||
45 | unsigned long handler_data; | ||
46 | }; | ||
47 | |||
48 | static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port) | ||
49 | { | ||
50 | if (mutex_lock_interruptible(&wka_port->mutex)) | ||
51 | return -ERESTARTSYS; | ||
52 | |||
53 | if (wka_port->status != ZFCP_WKA_PORT_ONLINE) { | ||
54 | wka_port->status = ZFCP_WKA_PORT_OPENING; | ||
55 | if (zfcp_fsf_open_wka_port(wka_port)) | ||
56 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
57 | } | ||
58 | |||
59 | mutex_unlock(&wka_port->mutex); | ||
60 | |||
61 | wait_event_timeout( | ||
62 | wka_port->completion_wq, | ||
63 | wka_port->status == ZFCP_WKA_PORT_ONLINE || | ||
64 | wka_port->status == ZFCP_WKA_PORT_OFFLINE, | ||
65 | HZ >> 1); | ||
66 | |||
67 | if (wka_port->status == ZFCP_WKA_PORT_ONLINE) { | ||
68 | atomic_inc(&wka_port->refcount); | ||
69 | return 0; | ||
70 | } | ||
71 | return -EIO; | ||
72 | } | ||
73 | |||
74 | static void zfcp_wka_port_offline(struct work_struct *work) | ||
75 | { | ||
76 | struct delayed_work *dw = container_of(work, struct delayed_work, work); | ||
77 | struct zfcp_wka_port *wka_port = | ||
78 | container_of(dw, struct zfcp_wka_port, work); | ||
79 | |||
80 | wait_event(wka_port->completion_wq, | ||
81 | atomic_read(&wka_port->refcount) == 0); | ||
82 | |||
83 | mutex_lock(&wka_port->mutex); | ||
84 | if ((atomic_read(&wka_port->refcount) != 0) || | ||
85 | (wka_port->status != ZFCP_WKA_PORT_ONLINE)) | ||
86 | goto out; | ||
87 | |||
88 | wka_port->status = ZFCP_WKA_PORT_CLOSING; | ||
89 | if (zfcp_fsf_close_wka_port(wka_port)) { | ||
90 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
91 | wake_up(&wka_port->completion_wq); | ||
92 | } | ||
93 | out: | ||
94 | mutex_unlock(&wka_port->mutex); | ||
95 | } | ||
96 | |||
97 | static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port) | ||
98 | { | ||
99 | if (atomic_dec_return(&wka_port->refcount) != 0) | ||
100 | return; | ||
101 | /* wait 10 miliseconds, other reqs might pop in */ | ||
102 | schedule_delayed_work(&wka_port->work, HZ / 100); | ||
103 | } | ||
104 | |||
105 | void zfcp_fc_nameserver_init(struct zfcp_adapter *adapter) | ||
106 | { | ||
107 | struct zfcp_wka_port *wka_port = &adapter->nsp; | ||
108 | |||
109 | init_waitqueue_head(&wka_port->completion_wq); | ||
110 | |||
111 | wka_port->adapter = adapter; | ||
112 | wka_port->d_id = ZFCP_DID_DIRECTORY_SERVICE; | ||
113 | |||
114 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
115 | atomic_set(&wka_port->refcount, 0); | ||
116 | mutex_init(&wka_port->mutex); | ||
117 | INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline); | ||
118 | } | ||
119 | |||
42 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | 120 | static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, |
43 | struct fcp_rscn_element *elem) | 121 | struct fcp_rscn_element *elem) |
44 | { | 122 | { |
@@ -47,10 +125,8 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, | |||
47 | 125 | ||
48 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 126 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
49 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { | 127 | list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { |
50 | if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) | ||
51 | continue; | ||
52 | /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ | 128 | /* FIXME: ZFCP_STATUS_PORT_DID_DID check is racy */ |
53 | if (!atomic_test_mask(ZFCP_STATUS_PORT_DID_DID, &port->status)) | 129 | if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID)) |
54 | /* Try to connect to unused ports anyway. */ | 130 | /* Try to connect to unused ports anyway. */ |
55 | zfcp_erp_port_reopen(port, | 131 | zfcp_erp_port_reopen(port, |
56 | ZFCP_STATUS_COMMON_ERP_FAILED, | 132 | ZFCP_STATUS_COMMON_ERP_FAILED, |
@@ -102,7 +178,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req) | |||
102 | schedule_work(&fsf_req->adapter->scan_work); | 178 | schedule_work(&fsf_req->adapter->scan_work); |
103 | } | 179 | } |
104 | 180 | ||
105 | static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, wwn_t wwpn) | 181 | static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn) |
106 | { | 182 | { |
107 | struct zfcp_adapter *adapter = req->adapter; | 183 | struct zfcp_adapter *adapter = req->adapter; |
108 | struct zfcp_port *port; | 184 | struct zfcp_port *port; |
@@ -157,7 +233,18 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) | |||
157 | zfcp_fc_incoming_rscn(fsf_req); | 233 | zfcp_fc_incoming_rscn(fsf_req); |
158 | } | 234 | } |
159 | 235 | ||
160 | static void zfcp_ns_gid_pn_handler(unsigned long data) | 236 | static void zfcp_fc_ns_handler(unsigned long data) |
237 | { | ||
238 | struct zfcp_fc_ns_handler_data *compl_rec = | ||
239 | (struct zfcp_fc_ns_handler_data *) data; | ||
240 | |||
241 | if (compl_rec->handler) | ||
242 | compl_rec->handler(compl_rec->handler_data); | ||
243 | |||
244 | complete(&compl_rec->done); | ||
245 | } | ||
246 | |||
247 | static void zfcp_fc_ns_gid_pn_eval(unsigned long data) | ||
161 | { | 248 | { |
162 | struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data; | 249 | struct zfcp_gid_pn_data *gid_pn = (struct zfcp_gid_pn_data *) data; |
163 | struct zfcp_send_ct *ct = &gid_pn->ct; | 250 | struct zfcp_send_ct *ct = &gid_pn->ct; |
@@ -166,43 +253,31 @@ static void zfcp_ns_gid_pn_handler(unsigned long data) | |||
166 | struct zfcp_port *port = gid_pn->port; | 253 | struct zfcp_port *port = gid_pn->port; |
167 | 254 | ||
168 | if (ct->status) | 255 | if (ct->status) |
169 | goto out; | 256 | return; |
170 | if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) { | 257 | if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) { |
171 | atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); | 258 | atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status); |
172 | goto out; | 259 | return; |
173 | } | 260 | } |
174 | /* paranoia */ | 261 | /* paranoia */ |
175 | if (ct_iu_req->wwpn != port->wwpn) | 262 | if (ct_iu_req->wwpn != port->wwpn) |
176 | goto out; | 263 | return; |
177 | /* looks like a valid d_id */ | 264 | /* looks like a valid d_id */ |
178 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; | 265 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; |
179 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); | 266 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); |
180 | out: | ||
181 | mempool_free(gid_pn, port->adapter->pool.data_gid_pn); | ||
182 | } | 267 | } |
183 | 268 | ||
184 | /** | 269 | int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action, |
185 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | 270 | struct zfcp_gid_pn_data *gid_pn) |
186 | * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed | ||
187 | * return: -ENOMEM on error, 0 otherwise | ||
188 | */ | ||
189 | int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action) | ||
190 | { | 271 | { |
191 | int ret; | ||
192 | struct zfcp_gid_pn_data *gid_pn; | ||
193 | struct zfcp_adapter *adapter = erp_action->adapter; | 272 | struct zfcp_adapter *adapter = erp_action->adapter; |
194 | 273 | struct zfcp_fc_ns_handler_data compl_rec; | |
195 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | 274 | int ret; |
196 | if (!gid_pn) | ||
197 | return -ENOMEM; | ||
198 | |||
199 | memset(gid_pn, 0, sizeof(*gid_pn)); | ||
200 | 275 | ||
201 | /* setup parameters for send generic command */ | 276 | /* setup parameters for send generic command */ |
202 | gid_pn->port = erp_action->port; | 277 | gid_pn->port = erp_action->port; |
203 | gid_pn->ct.port = adapter->nameserver_port; | 278 | gid_pn->ct.wka_port = &adapter->nsp; |
204 | gid_pn->ct.handler = zfcp_ns_gid_pn_handler; | 279 | gid_pn->ct.handler = zfcp_fc_ns_handler; |
205 | gid_pn->ct.handler_data = (unsigned long) gid_pn; | 280 | gid_pn->ct.handler_data = (unsigned long) &compl_rec; |
206 | gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; | 281 | gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT; |
207 | gid_pn->ct.req = &gid_pn->req; | 282 | gid_pn->ct.req = &gid_pn->req; |
208 | gid_pn->ct.resp = &gid_pn->resp; | 283 | gid_pn->ct.resp = &gid_pn->resp; |
@@ -222,10 +297,42 @@ int zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action) | |||
222 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; | 297 | gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_MAX_SIZE; |
223 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; | 298 | gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn; |
224 | 299 | ||
300 | init_completion(&compl_rec.done); | ||
301 | compl_rec.handler = zfcp_fc_ns_gid_pn_eval; | ||
302 | compl_rec.handler_data = (unsigned long) gid_pn; | ||
225 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, | 303 | ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp, |
226 | erp_action); | 304 | erp_action); |
305 | if (!ret) | ||
306 | wait_for_completion(&compl_rec.done); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request | ||
312 | * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed | ||
313 | * return: -ENOMEM on error, 0 otherwise | ||
314 | */ | ||
315 | int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action) | ||
316 | { | ||
317 | int ret; | ||
318 | struct zfcp_gid_pn_data *gid_pn; | ||
319 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
320 | |||
321 | gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC); | ||
322 | if (!gid_pn) | ||
323 | return -ENOMEM; | ||
324 | |||
325 | memset(gid_pn, 0, sizeof(*gid_pn)); | ||
326 | |||
327 | ret = zfcp_wka_port_get(&adapter->nsp); | ||
227 | if (ret) | 328 | if (ret) |
228 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | 329 | goto out; |
330 | |||
331 | ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn); | ||
332 | |||
333 | zfcp_wka_port_put(&adapter->nsp); | ||
334 | out: | ||
335 | mempool_free(gid_pn, adapter->pool.data_gid_pn); | ||
229 | return ret; | 336 | return ret; |
230 | } | 337 | } |
231 | 338 | ||
@@ -255,14 +362,14 @@ struct zfcp_els_adisc { | |||
255 | struct scatterlist req; | 362 | struct scatterlist req; |
256 | struct scatterlist resp; | 363 | struct scatterlist resp; |
257 | struct zfcp_ls_adisc ls_adisc; | 364 | struct zfcp_ls_adisc ls_adisc; |
258 | struct zfcp_ls_adisc_acc ls_adisc_acc; | 365 | struct zfcp_ls_adisc ls_adisc_acc; |
259 | }; | 366 | }; |
260 | 367 | ||
261 | static void zfcp_fc_adisc_handler(unsigned long data) | 368 | static void zfcp_fc_adisc_handler(unsigned long data) |
262 | { | 369 | { |
263 | struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data; | 370 | struct zfcp_els_adisc *adisc = (struct zfcp_els_adisc *) data; |
264 | struct zfcp_port *port = adisc->els.port; | 371 | struct zfcp_port *port = adisc->els.port; |
265 | struct zfcp_ls_adisc_acc *ls_adisc = &adisc->ls_adisc_acc; | 372 | struct zfcp_ls_adisc *ls_adisc = &adisc->ls_adisc_acc; |
266 | 373 | ||
267 | if (adisc->els.status) { | 374 | if (adisc->els.status) { |
268 | /* request rejected or timed out */ | 375 | /* request rejected or timed out */ |
@@ -295,7 +402,7 @@ static int zfcp_fc_adisc(struct zfcp_port *port) | |||
295 | sg_init_one(adisc->els.req, &adisc->ls_adisc, | 402 | sg_init_one(adisc->els.req, &adisc->ls_adisc, |
296 | sizeof(struct zfcp_ls_adisc)); | 403 | sizeof(struct zfcp_ls_adisc)); |
297 | sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc, | 404 | sg_init_one(adisc->els.resp, &adisc->ls_adisc_acc, |
298 | sizeof(struct zfcp_ls_adisc_acc)); | 405 | sizeof(struct zfcp_ls_adisc)); |
299 | 406 | ||
300 | adisc->els.req_count = 1; | 407 | adisc->els.req_count = 1; |
301 | adisc->els.resp_count = 1; | 408 | adisc->els.resp_count = 1; |
@@ -338,30 +445,6 @@ void zfcp_test_link(struct zfcp_port *port) | |||
338 | zfcp_erp_port_forced_reopen(port, 0, 65, NULL); | 445 | zfcp_erp_port_forced_reopen(port, 0, 65, NULL); |
339 | } | 446 | } |
340 | 447 | ||
341 | static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) | ||
342 | { | ||
343 | int ret; | ||
344 | |||
345 | if (!adapter->nameserver_port) | ||
346 | return -EINTR; | ||
347 | |||
348 | if (!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, | ||
349 | &adapter->nameserver_port->status)) { | ||
350 | ret = zfcp_erp_port_reopen(adapter->nameserver_port, 0, 148, | ||
351 | NULL); | ||
352 | if (ret) | ||
353 | return ret; | ||
354 | zfcp_erp_wait(adapter); | ||
355 | } | ||
356 | return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, | ||
357 | &adapter->nameserver_port->status); | ||
358 | } | ||
359 | |||
360 | static void zfcp_gpn_ft_handler(unsigned long _done) | ||
361 | { | ||
362 | complete((struct completion *)_done); | ||
363 | } | ||
364 | |||
365 | static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) | 448 | static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft) |
366 | { | 449 | { |
367 | struct scatterlist *sg = &gpn_ft->sg_req; | 450 | struct scatterlist *sg = &gpn_ft->sg_req; |
@@ -403,7 +486,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
403 | { | 486 | { |
404 | struct zfcp_send_ct *ct = &gpn_ft->ct; | 487 | struct zfcp_send_ct *ct = &gpn_ft->ct; |
405 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); | 488 | struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req); |
406 | struct completion done; | 489 | struct zfcp_fc_ns_handler_data compl_rec; |
407 | int ret; | 490 | int ret; |
408 | 491 | ||
409 | /* prepare CT IU for GPN_FT */ | 492 | /* prepare CT IU for GPN_FT */ |
@@ -420,19 +503,20 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft, | |||
420 | req->fc4_type = ZFCP_CT_SCSI_FCP; | 503 | req->fc4_type = ZFCP_CT_SCSI_FCP; |
421 | 504 | ||
422 | /* prepare zfcp_send_ct */ | 505 | /* prepare zfcp_send_ct */ |
423 | ct->port = adapter->nameserver_port; | 506 | ct->wka_port = &adapter->nsp; |
424 | ct->handler = zfcp_gpn_ft_handler; | 507 | ct->handler = zfcp_fc_ns_handler; |
425 | ct->handler_data = (unsigned long)&done; | 508 | ct->handler_data = (unsigned long)&compl_rec; |
426 | ct->timeout = 10; | 509 | ct->timeout = 10; |
427 | ct->req = &gpn_ft->sg_req; | 510 | ct->req = &gpn_ft->sg_req; |
428 | ct->resp = gpn_ft->sg_resp; | 511 | ct->resp = gpn_ft->sg_resp; |
429 | ct->req_count = 1; | 512 | ct->req_count = 1; |
430 | ct->resp_count = ZFCP_GPN_FT_BUFFERS; | 513 | ct->resp_count = ZFCP_GPN_FT_BUFFERS; |
431 | 514 | ||
432 | init_completion(&done); | 515 | init_completion(&compl_rec.done); |
516 | compl_rec.handler = NULL; | ||
433 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); | 517 | ret = zfcp_fsf_send_ct(ct, NULL, NULL); |
434 | if (!ret) | 518 | if (!ret) |
435 | wait_for_completion(&done); | 519 | wait_for_completion(&compl_rec.done); |
436 | return ret; | 520 | return ret; |
437 | } | 521 | } |
438 | 522 | ||
@@ -442,9 +526,8 @@ static void zfcp_validate_port(struct zfcp_port *port) | |||
442 | 526 | ||
443 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); | 527 | atomic_clear_mask(ZFCP_STATUS_COMMON_NOESC, &port->status); |
444 | 528 | ||
445 | if (port == adapter->nameserver_port) | 529 | if ((port->supported_classes != 0) || |
446 | return; | 530 | !list_empty(&port->unit_list_head)) { |
447 | if ((port->supported_classes != 0) || (port->units != 0)) { | ||
448 | zfcp_port_put(port); | 531 | zfcp_port_put(port); |
449 | return; | 532 | return; |
450 | } | 533 | } |
@@ -460,7 +543,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) | |||
460 | struct scatterlist *sg = gpn_ft->sg_resp; | 543 | struct scatterlist *sg = gpn_ft->sg_resp; |
461 | struct ct_hdr *hdr = sg_virt(sg); | 544 | struct ct_hdr *hdr = sg_virt(sg); |
462 | struct gpn_ft_resp_acc *acc = sg_virt(sg); | 545 | struct gpn_ft_resp_acc *acc = sg_virt(sg); |
463 | struct zfcp_adapter *adapter = ct->port->adapter; | 546 | struct zfcp_adapter *adapter = ct->wka_port->adapter; |
464 | struct zfcp_port *port, *tmp; | 547 | struct zfcp_port *port, *tmp; |
465 | u32 d_id; | 548 | u32 d_id; |
466 | int ret = 0, x, last = 0; | 549 | int ret = 0, x, last = 0; |
@@ -490,6 +573,9 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) | |||
490 | d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | | 573 | d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | |
491 | acc->port_id[2]; | 574 | acc->port_id[2]; |
492 | 575 | ||
576 | /* don't attach ports with a well known address */ | ||
577 | if ((d_id & ZFCP_DID_WKA) == ZFCP_DID_WKA) | ||
578 | continue; | ||
493 | /* skip the adapter's port and known remote ports */ | 579 | /* skip the adapter's port and known remote ports */ |
494 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) | 580 | if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) |
495 | continue; | 581 | continue; |
@@ -528,13 +614,15 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
528 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) | 614 | if (fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPORT) |
529 | return 0; | 615 | return 0; |
530 | 616 | ||
531 | ret = zfcp_scan_get_nameserver(adapter); | 617 | ret = zfcp_wka_port_get(&adapter->nsp); |
532 | if (ret) | 618 | if (ret) |
533 | return ret; | 619 | return ret; |
534 | 620 | ||
535 | gpn_ft = zfcp_alloc_sg_env(); | 621 | gpn_ft = zfcp_alloc_sg_env(); |
536 | if (!gpn_ft) | 622 | if (!gpn_ft) { |
537 | return -ENOMEM; | 623 | ret = -ENOMEM; |
624 | goto out; | ||
625 | } | ||
538 | 626 | ||
539 | for (i = 0; i < 3; i++) { | 627 | for (i = 0; i < 3; i++) { |
540 | ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); | 628 | ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter); |
@@ -547,7 +635,8 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter) | |||
547 | } | 635 | } |
548 | } | 636 | } |
549 | zfcp_free_sg_env(gpn_ft); | 637 | zfcp_free_sg_env(gpn_ft); |
550 | 638 | out: | |
639 | zfcp_wka_port_put(&adapter->nsp); | ||
551 | return ret; | 640 | return ret; |
552 | } | 641 | } |
553 | 642 | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 49dbeb754e5f..739356a5c123 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -50,19 +50,16 @@ static u32 fsf_qtcb_type[] = { | |||
50 | [FSF_QTCB_UPLOAD_CONTROL_FILE] = FSF_SUPPORT_COMMAND | 50 | [FSF_QTCB_UPLOAD_CONTROL_FILE] = FSF_SUPPORT_COMMAND |
51 | }; | 51 | }; |
52 | 52 | ||
53 | static const char *zfcp_act_subtable_type[] = { | ||
54 | "unknown", "OS", "WWPN", "DID", "LUN" | ||
55 | }; | ||
56 | |||
57 | static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) | 53 | static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) |
58 | { | 54 | { |
59 | u16 subtable = table >> 16; | 55 | u16 subtable = table >> 16; |
60 | u16 rule = table & 0xffff; | 56 | u16 rule = table & 0xffff; |
57 | const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" }; | ||
61 | 58 | ||
62 | if (subtable && subtable < ARRAY_SIZE(zfcp_act_subtable_type)) | 59 | if (subtable && subtable < ARRAY_SIZE(act_type)) |
63 | dev_warn(&adapter->ccw_device->dev, | 60 | dev_warn(&adapter->ccw_device->dev, |
64 | "Access denied in subtable %s, rule %d.\n", | 61 | "Access denied according to ACT rule type %s, " |
65 | zfcp_act_subtable_type[subtable], rule); | 62 | "rule %d\n", act_type[subtable], rule); |
66 | } | 63 | } |
67 | 64 | ||
68 | static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req, | 65 | static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req, |
@@ -70,8 +67,8 @@ static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req, | |||
70 | { | 67 | { |
71 | struct fsf_qtcb_header *header = &req->qtcb->header; | 68 | struct fsf_qtcb_header *header = &req->qtcb->header; |
72 | dev_warn(&req->adapter->ccw_device->dev, | 69 | dev_warn(&req->adapter->ccw_device->dev, |
73 | "Access denied, cannot send command to port 0x%016Lx.\n", | 70 | "Access denied to port 0x%016Lx\n", |
74 | port->wwpn); | 71 | (unsigned long long)port->wwpn); |
75 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); | 72 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); |
76 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); | 73 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); |
77 | zfcp_erp_port_access_denied(port, 55, req); | 74 | zfcp_erp_port_access_denied(port, 55, req); |
@@ -83,8 +80,9 @@ static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req, | |||
83 | { | 80 | { |
84 | struct fsf_qtcb_header *header = &req->qtcb->header; | 81 | struct fsf_qtcb_header *header = &req->qtcb->header; |
85 | dev_warn(&req->adapter->ccw_device->dev, | 82 | dev_warn(&req->adapter->ccw_device->dev, |
86 | "Access denied for unit 0x%016Lx on port 0x%016Lx.\n", | 83 | "Access denied to unit 0x%016Lx on port 0x%016Lx\n", |
87 | unit->fcp_lun, unit->port->wwpn); | 84 | (unsigned long long)unit->fcp_lun, |
85 | (unsigned long long)unit->port->wwpn); | ||
88 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); | 86 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]); |
89 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); | 87 | zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]); |
90 | zfcp_erp_unit_access_denied(unit, 59, req); | 88 | zfcp_erp_unit_access_denied(unit, 59, req); |
@@ -93,9 +91,8 @@ static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req, | |||
93 | 91 | ||
94 | static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req) | 92 | static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req) |
95 | { | 93 | { |
96 | dev_err(&req->adapter->ccw_device->dev, | 94 | dev_err(&req->adapter->ccw_device->dev, "FCP device not " |
97 | "Required FC class not supported by adapter, " | 95 | "operational because of an unsupported FC class\n"); |
98 | "shutting down adapter.\n"); | ||
99 | zfcp_erp_adapter_shutdown(req->adapter, 0, 123, req); | 96 | zfcp_erp_adapter_shutdown(req->adapter, 0, 123, req); |
100 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 97 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
101 | } | 98 | } |
@@ -171,42 +168,6 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) | |||
171 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 168 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
172 | } | 169 | } |
173 | 170 | ||
174 | static void zfcp_fsf_bit_error_threshold(struct zfcp_fsf_req *req) | ||
175 | { | ||
176 | struct zfcp_adapter *adapter = req->adapter; | ||
177 | struct fsf_status_read_buffer *sr_buf = req->data; | ||
178 | struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error; | ||
179 | |||
180 | dev_warn(&adapter->ccw_device->dev, | ||
181 | "Warning: bit error threshold data " | ||
182 | "received for the adapter: " | ||
183 | "link failures = %i, loss of sync errors = %i, " | ||
184 | "loss of signal errors = %i, " | ||
185 | "primitive sequence errors = %i, " | ||
186 | "invalid transmission word errors = %i, " | ||
187 | "CRC errors = %i).\n", | ||
188 | err->link_failure_error_count, | ||
189 | err->loss_of_sync_error_count, | ||
190 | err->loss_of_signal_error_count, | ||
191 | err->primitive_sequence_error_count, | ||
192 | err->invalid_transmission_word_error_count, | ||
193 | err->crc_error_count); | ||
194 | dev_warn(&adapter->ccw_device->dev, | ||
195 | "Additional bit error threshold data of the adapter: " | ||
196 | "primitive sequence event time-outs = %i, " | ||
197 | "elastic buffer overrun errors = %i, " | ||
198 | "advertised receive buffer-to-buffer credit = %i, " | ||
199 | "current receice buffer-to-buffer credit = %i, " | ||
200 | "advertised transmit buffer-to-buffer credit = %i, " | ||
201 | "current transmit buffer-to-buffer credit = %i).\n", | ||
202 | err->primitive_sequence_event_timeout_count, | ||
203 | err->elastic_buffer_overrun_error_count, | ||
204 | err->advertised_receive_b2b_credit, | ||
205 | err->current_receive_b2b_credit, | ||
206 | err->advertised_transmit_b2b_credit, | ||
207 | err->current_transmit_b2b_credit); | ||
208 | } | ||
209 | |||
210 | static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id, | 171 | static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id, |
211 | struct fsf_link_down_info *link_down) | 172 | struct fsf_link_down_info *link_down) |
212 | { | 173 | { |
@@ -223,62 +184,66 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id, | |||
223 | switch (link_down->error_code) { | 184 | switch (link_down->error_code) { |
224 | case FSF_PSQ_LINK_NO_LIGHT: | 185 | case FSF_PSQ_LINK_NO_LIGHT: |
225 | dev_warn(&req->adapter->ccw_device->dev, | 186 | dev_warn(&req->adapter->ccw_device->dev, |
226 | "The local link is down: no light detected.\n"); | 187 | "There is no light signal from the local " |
188 | "fibre channel cable\n"); | ||
227 | break; | 189 | break; |
228 | case FSF_PSQ_LINK_WRAP_PLUG: | 190 | case FSF_PSQ_LINK_WRAP_PLUG: |
229 | dev_warn(&req->adapter->ccw_device->dev, | 191 | dev_warn(&req->adapter->ccw_device->dev, |
230 | "The local link is down: wrap plug detected.\n"); | 192 | "There is a wrap plug instead of a fibre " |
193 | "channel cable\n"); | ||
231 | break; | 194 | break; |
232 | case FSF_PSQ_LINK_NO_FCP: | 195 | case FSF_PSQ_LINK_NO_FCP: |
233 | dev_warn(&req->adapter->ccw_device->dev, | 196 | dev_warn(&req->adapter->ccw_device->dev, |
234 | "The local link is down: " | 197 | "The adjacent fibre channel node does not " |
235 | "adjacent node on link does not support FCP.\n"); | 198 | "support FCP\n"); |
236 | break; | 199 | break; |
237 | case FSF_PSQ_LINK_FIRMWARE_UPDATE: | 200 | case FSF_PSQ_LINK_FIRMWARE_UPDATE: |
238 | dev_warn(&req->adapter->ccw_device->dev, | 201 | dev_warn(&req->adapter->ccw_device->dev, |
239 | "The local link is down: " | 202 | "The FCP device is suspended because of a " |
240 | "firmware update in progress.\n"); | 203 | "firmware update\n"); |
241 | break; | 204 | break; |
242 | case FSF_PSQ_LINK_INVALID_WWPN: | 205 | case FSF_PSQ_LINK_INVALID_WWPN: |
243 | dev_warn(&req->adapter->ccw_device->dev, | 206 | dev_warn(&req->adapter->ccw_device->dev, |
244 | "The local link is down: " | 207 | "The FCP device detected a WWPN that is " |
245 | "duplicate or invalid WWPN detected.\n"); | 208 | "duplicate or not valid\n"); |
246 | break; | 209 | break; |
247 | case FSF_PSQ_LINK_NO_NPIV_SUPPORT: | 210 | case FSF_PSQ_LINK_NO_NPIV_SUPPORT: |
248 | dev_warn(&req->adapter->ccw_device->dev, | 211 | dev_warn(&req->adapter->ccw_device->dev, |
249 | "The local link is down: " | 212 | "The fibre channel fabric does not support NPIV\n"); |
250 | "no support for NPIV by Fabric.\n"); | ||
251 | break; | 213 | break; |
252 | case FSF_PSQ_LINK_NO_FCP_RESOURCES: | 214 | case FSF_PSQ_LINK_NO_FCP_RESOURCES: |
253 | dev_warn(&req->adapter->ccw_device->dev, | 215 | dev_warn(&req->adapter->ccw_device->dev, |
254 | "The local link is down: " | 216 | "The FCP adapter cannot support more NPIV ports\n"); |
255 | "out of resource in FCP daughtercard.\n"); | ||
256 | break; | 217 | break; |
257 | case FSF_PSQ_LINK_NO_FABRIC_RESOURCES: | 218 | case FSF_PSQ_LINK_NO_FABRIC_RESOURCES: |
258 | dev_warn(&req->adapter->ccw_device->dev, | 219 | dev_warn(&req->adapter->ccw_device->dev, |
259 | "The local link is down: " | 220 | "The adjacent switch cannot support " |
260 | "out of resource in Fabric.\n"); | 221 | "more NPIV ports\n"); |
261 | break; | 222 | break; |
262 | case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE: | 223 | case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE: |
263 | dev_warn(&req->adapter->ccw_device->dev, | 224 | dev_warn(&req->adapter->ccw_device->dev, |
264 | "The local link is down: " | 225 | "The FCP adapter could not log in to the " |
265 | "unable to login to Fabric.\n"); | 226 | "fibre channel fabric\n"); |
266 | break; | 227 | break; |
267 | case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED: | 228 | case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED: |
268 | dev_warn(&req->adapter->ccw_device->dev, | 229 | dev_warn(&req->adapter->ccw_device->dev, |
269 | "WWPN assignment file corrupted on adapter.\n"); | 230 | "The WWPN assignment file on the FCP adapter " |
231 | "has been damaged\n"); | ||
270 | break; | 232 | break; |
271 | case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED: | 233 | case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED: |
272 | dev_warn(&req->adapter->ccw_device->dev, | 234 | dev_warn(&req->adapter->ccw_device->dev, |
273 | "Mode table corrupted on adapter.\n"); | 235 | "The mode table on the FCP adapter " |
236 | "has been damaged\n"); | ||
274 | break; | 237 | break; |
275 | case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT: | 238 | case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT: |
276 | dev_warn(&req->adapter->ccw_device->dev, | 239 | dev_warn(&req->adapter->ccw_device->dev, |
277 | "No WWPN for assignment table on adapter.\n"); | 240 | "All NPIV ports on the FCP adapter have " |
241 | "been assigned\n"); | ||
278 | break; | 242 | break; |
279 | default: | 243 | default: |
280 | dev_warn(&req->adapter->ccw_device->dev, | 244 | dev_warn(&req->adapter->ccw_device->dev, |
281 | "The local link to adapter is down.\n"); | 245 | "The link between the FCP adapter and " |
246 | "the FC fabric is down\n"); | ||
282 | } | 247 | } |
283 | out: | 248 | out: |
284 | zfcp_erp_adapter_failed(adapter, id, req); | 249 | zfcp_erp_adapter_failed(adapter, id, req); |
@@ -286,27 +251,18 @@ out: | |||
286 | 251 | ||
287 | static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req) | 252 | static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req) |
288 | { | 253 | { |
289 | struct zfcp_adapter *adapter = req->adapter; | ||
290 | struct fsf_status_read_buffer *sr_buf = req->data; | 254 | struct fsf_status_read_buffer *sr_buf = req->data; |
291 | struct fsf_link_down_info *ldi = | 255 | struct fsf_link_down_info *ldi = |
292 | (struct fsf_link_down_info *) &sr_buf->payload; | 256 | (struct fsf_link_down_info *) &sr_buf->payload; |
293 | 257 | ||
294 | switch (sr_buf->status_subtype) { | 258 | switch (sr_buf->status_subtype) { |
295 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: | 259 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: |
296 | dev_warn(&adapter->ccw_device->dev, | ||
297 | "Physical link is down.\n"); | ||
298 | zfcp_fsf_link_down_info_eval(req, 38, ldi); | 260 | zfcp_fsf_link_down_info_eval(req, 38, ldi); |
299 | break; | 261 | break; |
300 | case FSF_STATUS_READ_SUB_FDISC_FAILED: | 262 | case FSF_STATUS_READ_SUB_FDISC_FAILED: |
301 | dev_warn(&adapter->ccw_device->dev, | ||
302 | "Local link is down " | ||
303 | "due to failed FDISC login.\n"); | ||
304 | zfcp_fsf_link_down_info_eval(req, 39, ldi); | 263 | zfcp_fsf_link_down_info_eval(req, 39, ldi); |
305 | break; | 264 | break; |
306 | case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: | 265 | case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: |
307 | dev_warn(&adapter->ccw_device->dev, | ||
308 | "Local link is down " | ||
309 | "due to firmware update on adapter.\n"); | ||
310 | zfcp_fsf_link_down_info_eval(req, 40, NULL); | 266 | zfcp_fsf_link_down_info_eval(req, 40, NULL); |
311 | }; | 267 | }; |
312 | } | 268 | } |
@@ -335,14 +291,17 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
335 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: | 291 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: |
336 | break; | 292 | break; |
337 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: | 293 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: |
338 | zfcp_fsf_bit_error_threshold(req); | 294 | dev_warn(&adapter->ccw_device->dev, |
295 | "The error threshold for checksum statistics " | ||
296 | "has been exceeded\n"); | ||
297 | zfcp_hba_dbf_event_berr(adapter, req); | ||
339 | break; | 298 | break; |
340 | case FSF_STATUS_READ_LINK_DOWN: | 299 | case FSF_STATUS_READ_LINK_DOWN: |
341 | zfcp_fsf_status_read_link_down(req); | 300 | zfcp_fsf_status_read_link_down(req); |
342 | break; | 301 | break; |
343 | case FSF_STATUS_READ_LINK_UP: | 302 | case FSF_STATUS_READ_LINK_UP: |
344 | dev_info(&adapter->ccw_device->dev, | 303 | dev_info(&adapter->ccw_device->dev, |
345 | "Local link was replugged.\n"); | 304 | "The local link has been restored\n"); |
346 | /* All ports should be marked as ready to run again */ | 305 | /* All ports should be marked as ready to run again */ |
347 | zfcp_erp_modify_adapter_status(adapter, 30, NULL, | 306 | zfcp_erp_modify_adapter_status(adapter, 30, NULL, |
348 | ZFCP_STATUS_COMMON_RUNNING, | 307 | ZFCP_STATUS_COMMON_RUNNING, |
@@ -370,7 +329,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
370 | zfcp_fsf_req_free(req); | 329 | zfcp_fsf_req_free(req); |
371 | 330 | ||
372 | atomic_inc(&adapter->stat_miss); | 331 | atomic_inc(&adapter->stat_miss); |
373 | schedule_work(&adapter->stat_work); | 332 | queue_work(zfcp_data.work_queue, &adapter->stat_work); |
374 | } | 333 | } |
375 | 334 | ||
376 | static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req) | 335 | static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req) |
@@ -386,8 +345,8 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req) | |||
386 | break; | 345 | break; |
387 | case FSF_SQ_NO_RECOM: | 346 | case FSF_SQ_NO_RECOM: |
388 | dev_err(&req->adapter->ccw_device->dev, | 347 | dev_err(&req->adapter->ccw_device->dev, |
389 | "No recommendation could be given for a " | 348 | "The FCP adapter reported a problem " |
390 | "problem on the adapter.\n"); | 349 | "that cannot be recovered\n"); |
391 | zfcp_erp_adapter_shutdown(req->adapter, 0, 121, req); | 350 | zfcp_erp_adapter_shutdown(req->adapter, 0, 121, req); |
392 | break; | 351 | break; |
393 | } | 352 | } |
@@ -403,8 +362,7 @@ static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req) | |||
403 | switch (req->qtcb->header.fsf_status) { | 362 | switch (req->qtcb->header.fsf_status) { |
404 | case FSF_UNKNOWN_COMMAND: | 363 | case FSF_UNKNOWN_COMMAND: |
405 | dev_err(&req->adapter->ccw_device->dev, | 364 | dev_err(&req->adapter->ccw_device->dev, |
406 | "Command issued by the device driver (0x%x) is " | 365 | "The FCP adapter does not recognize the command 0x%x\n", |
407 | "not known by the adapter.\n", | ||
408 | req->qtcb->header.fsf_command); | 366 | req->qtcb->header.fsf_command); |
409 | zfcp_erp_adapter_shutdown(req->adapter, 0, 120, req); | 367 | zfcp_erp_adapter_shutdown(req->adapter, 0, 120, req); |
410 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 368 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
@@ -435,11 +393,9 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) | |||
435 | return; | 393 | return; |
436 | case FSF_PROT_QTCB_VERSION_ERROR: | 394 | case FSF_PROT_QTCB_VERSION_ERROR: |
437 | dev_err(&adapter->ccw_device->dev, | 395 | dev_err(&adapter->ccw_device->dev, |
438 | "The QTCB version requested by zfcp (0x%x) is not " | 396 | "QTCB version 0x%x not supported by FCP adapter " |
439 | "supported by the FCP adapter (lowest supported " | 397 | "(0x%x to 0x%x)\n", FSF_QTCB_CURRENT_VERSION, |
440 | "0x%x, highest supported 0x%x).\n", | 398 | psq->word[0], psq->word[1]); |
441 | FSF_QTCB_CURRENT_VERSION, psq->word[0], | ||
442 | psq->word[1]); | ||
443 | zfcp_erp_adapter_shutdown(adapter, 0, 117, req); | 399 | zfcp_erp_adapter_shutdown(adapter, 0, 117, req); |
444 | break; | 400 | break; |
445 | case FSF_PROT_ERROR_STATE: | 401 | case FSF_PROT_ERROR_STATE: |
@@ -449,8 +405,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) | |||
449 | break; | 405 | break; |
450 | case FSF_PROT_UNSUPP_QTCB_TYPE: | 406 | case FSF_PROT_UNSUPP_QTCB_TYPE: |
451 | dev_err(&adapter->ccw_device->dev, | 407 | dev_err(&adapter->ccw_device->dev, |
452 | "Packet header type used by the device driver is " | 408 | "The QTCB type is not supported by the FCP adapter\n"); |
453 | "incompatible with that used on the adapter.\n"); | ||
454 | zfcp_erp_adapter_shutdown(adapter, 0, 118, req); | 409 | zfcp_erp_adapter_shutdown(adapter, 0, 118, req); |
455 | break; | 410 | break; |
456 | case FSF_PROT_HOST_CONNECTION_INITIALIZING: | 411 | case FSF_PROT_HOST_CONNECTION_INITIALIZING: |
@@ -459,7 +414,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) | |||
459 | break; | 414 | break; |
460 | case FSF_PROT_DUPLICATE_REQUEST_ID: | 415 | case FSF_PROT_DUPLICATE_REQUEST_ID: |
461 | dev_err(&adapter->ccw_device->dev, | 416 | dev_err(&adapter->ccw_device->dev, |
462 | "The request identifier 0x%Lx is ambiguous.\n", | 417 | "0x%Lx is an ambiguous request identifier\n", |
463 | (unsigned long long)qtcb->bottom.support.req_handle); | 418 | (unsigned long long)qtcb->bottom.support.req_handle); |
464 | zfcp_erp_adapter_shutdown(adapter, 0, 78, req); | 419 | zfcp_erp_adapter_shutdown(adapter, 0, 78, req); |
465 | break; | 420 | break; |
@@ -479,9 +434,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) | |||
479 | break; | 434 | break; |
480 | default: | 435 | default: |
481 | dev_err(&adapter->ccw_device->dev, | 436 | dev_err(&adapter->ccw_device->dev, |
482 | "Transfer protocol status information" | 437 | "0x%x is not a valid transfer protocol status\n", |
483 | "provided by the adapter (0x%x) " | ||
484 | "is not compatible with the device driver.\n", | ||
485 | qtcb->prefix.prot_status); | 438 | qtcb->prefix.prot_status); |
486 | zfcp_erp_adapter_shutdown(adapter, 0, 119, req); | 439 | zfcp_erp_adapter_shutdown(adapter, 0, 119, req); |
487 | } | 440 | } |
@@ -559,33 +512,17 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) | |||
559 | adapter->peer_wwpn = bottom->plogi_payload.wwpn; | 512 | adapter->peer_wwpn = bottom->plogi_payload.wwpn; |
560 | adapter->peer_wwnn = bottom->plogi_payload.wwnn; | 513 | adapter->peer_wwnn = bottom->plogi_payload.wwnn; |
561 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; | 514 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; |
562 | if (req->erp_action) | ||
563 | dev_info(&adapter->ccw_device->dev, | ||
564 | "Point-to-Point fibrechannel " | ||
565 | "configuration detected.\n"); | ||
566 | break; | 515 | break; |
567 | case FSF_TOPO_FABRIC: | 516 | case FSF_TOPO_FABRIC: |
568 | fc_host_port_type(shost) = FC_PORTTYPE_NPORT; | 517 | fc_host_port_type(shost) = FC_PORTTYPE_NPORT; |
569 | if (req->erp_action) | ||
570 | dev_info(&adapter->ccw_device->dev, | ||
571 | "Switched fabric fibrechannel " | ||
572 | "network detected.\n"); | ||
573 | break; | 518 | break; |
574 | case FSF_TOPO_AL: | 519 | case FSF_TOPO_AL: |
575 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; | 520 | fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; |
576 | dev_err(&adapter->ccw_device->dev, | ||
577 | "Unsupported arbitrated loop fibrechannel " | ||
578 | "topology detected, shutting down " | ||
579 | "adapter.\n"); | ||
580 | zfcp_erp_adapter_shutdown(adapter, 0, 127, req); | ||
581 | return -EIO; | ||
582 | default: | 521 | default: |
583 | fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; | ||
584 | dev_err(&adapter->ccw_device->dev, | 522 | dev_err(&adapter->ccw_device->dev, |
585 | "The fibrechannel topology reported by the" | 523 | "Unknown or unsupported arbitrated loop " |
586 | " adapter is not known by the zfcp driver," | 524 | "fibre channel topology detected\n"); |
587 | " shutting down adapter.\n"); | 525 | zfcp_erp_adapter_shutdown(adapter, 0, 127, req); |
588 | zfcp_erp_adapter_shutdown(adapter, 0, 128, req); | ||
589 | return -EIO; | 526 | return -EIO; |
590 | } | 527 | } |
591 | 528 | ||
@@ -616,11 +553,9 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) | |||
616 | 553 | ||
617 | if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { | 554 | if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { |
618 | dev_err(&adapter->ccw_device->dev, | 555 | dev_err(&adapter->ccw_device->dev, |
619 | "Maximum QTCB size (%d bytes) allowed by " | 556 | "FCP adapter maximum QTCB size (%d bytes) " |
620 | "the adapter is lower than the minimum " | 557 | "is too small\n", |
621 | "required by the driver (%ld bytes).\n", | 558 | bottom->max_qtcb_size); |
622 | bottom->max_qtcb_size, | ||
623 | sizeof(struct fsf_qtcb)); | ||
624 | zfcp_erp_adapter_shutdown(adapter, 0, 129, req); | 559 | zfcp_erp_adapter_shutdown(adapter, 0, 129, req); |
625 | return; | 560 | return; |
626 | } | 561 | } |
@@ -656,15 +591,15 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) | |||
656 | 591 | ||
657 | if (FSF_QTCB_CURRENT_VERSION < bottom->low_qtcb_version) { | 592 | if (FSF_QTCB_CURRENT_VERSION < bottom->low_qtcb_version) { |
658 | dev_err(&adapter->ccw_device->dev, | 593 | dev_err(&adapter->ccw_device->dev, |
659 | "The adapter only supports newer control block " | 594 | "The FCP adapter only supports newer " |
660 | "versions, try updated device driver.\n"); | 595 | "control block versions\n"); |
661 | zfcp_erp_adapter_shutdown(adapter, 0, 125, req); | 596 | zfcp_erp_adapter_shutdown(adapter, 0, 125, req); |
662 | return; | 597 | return; |
663 | } | 598 | } |
664 | if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) { | 599 | if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) { |
665 | dev_err(&adapter->ccw_device->dev, | 600 | dev_err(&adapter->ccw_device->dev, |
666 | "The adapter only supports older control block " | 601 | "The FCP adapter only supports older " |
667 | "versions, consider a microcode upgrade.\n"); | 602 | "control block versions\n"); |
668 | zfcp_erp_adapter_shutdown(adapter, 0, 126, req); | 603 | zfcp_erp_adapter_shutdown(adapter, 0, 126, req); |
669 | } | 604 | } |
670 | } | 605 | } |
@@ -688,7 +623,6 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req) | |||
688 | 623 | ||
689 | static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) | 624 | static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) |
690 | { | 625 | { |
691 | struct zfcp_adapter *adapter = req->adapter; | ||
692 | struct fsf_qtcb *qtcb = req->qtcb; | 626 | struct fsf_qtcb *qtcb = req->qtcb; |
693 | 627 | ||
694 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 628 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
@@ -697,38 +631,47 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) | |||
697 | switch (qtcb->header.fsf_status) { | 631 | switch (qtcb->header.fsf_status) { |
698 | case FSF_GOOD: | 632 | case FSF_GOOD: |
699 | zfcp_fsf_exchange_port_evaluate(req); | 633 | zfcp_fsf_exchange_port_evaluate(req); |
700 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | ||
701 | break; | 634 | break; |
702 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: | 635 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: |
703 | zfcp_fsf_exchange_port_evaluate(req); | 636 | zfcp_fsf_exchange_port_evaluate(req); |
704 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | ||
705 | zfcp_fsf_link_down_info_eval(req, 43, | 637 | zfcp_fsf_link_down_info_eval(req, 43, |
706 | &qtcb->header.fsf_status_qual.link_down_info); | 638 | &qtcb->header.fsf_status_qual.link_down_info); |
707 | break; | 639 | break; |
708 | } | 640 | } |
709 | } | 641 | } |
710 | 642 | ||
711 | static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue) | 643 | static int zfcp_fsf_sbal_check(struct zfcp_adapter *adapter) |
712 | { | 644 | { |
713 | spin_lock_bh(&queue->lock); | 645 | struct zfcp_qdio_queue *req_q = &adapter->req_q; |
714 | if (atomic_read(&queue->count)) | 646 | |
647 | spin_lock_bh(&adapter->req_q_lock); | ||
648 | if (atomic_read(&req_q->count)) | ||
715 | return 1; | 649 | return 1; |
716 | spin_unlock_bh(&queue->lock); | 650 | spin_unlock_bh(&adapter->req_q_lock); |
717 | return 0; | 651 | return 0; |
718 | } | 652 | } |
719 | 653 | ||
654 | static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter) | ||
655 | { | ||
656 | unsigned int count = atomic_read(&adapter->req_q.count); | ||
657 | if (!count) | ||
658 | atomic_inc(&adapter->qdio_outb_full); | ||
659 | return count > 0; | ||
660 | } | ||
661 | |||
720 | static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | 662 | static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) |
721 | { | 663 | { |
722 | long ret; | 664 | long ret; |
723 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | ||
724 | 665 | ||
725 | spin_unlock_bh(&req_q->lock); | 666 | spin_unlock_bh(&adapter->req_q_lock); |
726 | ret = wait_event_interruptible_timeout(adapter->request_wq, | 667 | ret = wait_event_interruptible_timeout(adapter->request_wq, |
727 | zfcp_fsf_sbal_check(req_q), 5 * HZ); | 668 | zfcp_fsf_sbal_check(adapter), 5 * HZ); |
728 | if (ret > 0) | 669 | if (ret > 0) |
729 | return 0; | 670 | return 0; |
671 | if (!ret) | ||
672 | atomic_inc(&adapter->qdio_outb_full); | ||
730 | 673 | ||
731 | spin_lock_bh(&req_q->lock); | 674 | spin_lock_bh(&adapter->req_q_lock); |
732 | return -EIO; | 675 | return -EIO; |
733 | } | 676 | } |
734 | 677 | ||
@@ -765,7 +708,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, | |||
765 | u32 fsf_cmd, int req_flags, | 708 | u32 fsf_cmd, int req_flags, |
766 | mempool_t *pool) | 709 | mempool_t *pool) |
767 | { | 710 | { |
768 | volatile struct qdio_buffer_element *sbale; | 711 | struct qdio_buffer_element *sbale; |
769 | 712 | ||
770 | struct zfcp_fsf_req *req; | 713 | struct zfcp_fsf_req *req; |
771 | struct zfcp_qdio_queue *req_q = &adapter->req_q; | 714 | struct zfcp_qdio_queue *req_q = &adapter->req_q; |
@@ -867,10 +810,10 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) | |||
867 | { | 810 | { |
868 | struct zfcp_fsf_req *req; | 811 | struct zfcp_fsf_req *req; |
869 | struct fsf_status_read_buffer *sr_buf; | 812 | struct fsf_status_read_buffer *sr_buf; |
870 | volatile struct qdio_buffer_element *sbale; | 813 | struct qdio_buffer_element *sbale; |
871 | int retval = -EIO; | 814 | int retval = -EIO; |
872 | 815 | ||
873 | spin_lock_bh(&adapter->req_q.lock); | 816 | spin_lock_bh(&adapter->req_q_lock); |
874 | if (zfcp_fsf_req_sbal_get(adapter)) | 817 | if (zfcp_fsf_req_sbal_get(adapter)) |
875 | goto out; | 818 | goto out; |
876 | 819 | ||
@@ -910,7 +853,7 @@ failed_buf: | |||
910 | zfcp_fsf_req_free(req); | 853 | zfcp_fsf_req_free(req); |
911 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); | 854 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); |
912 | out: | 855 | out: |
913 | spin_unlock_bh(&adapter->req_q.lock); | 856 | spin_unlock_bh(&adapter->req_q_lock); |
914 | return retval; | 857 | return retval; |
915 | } | 858 | } |
916 | 859 | ||
@@ -980,11 +923,11 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
980 | struct zfcp_unit *unit, | 923 | struct zfcp_unit *unit, |
981 | int req_flags) | 924 | int req_flags) |
982 | { | 925 | { |
983 | volatile struct qdio_buffer_element *sbale; | 926 | struct qdio_buffer_element *sbale; |
984 | struct zfcp_fsf_req *req = NULL; | 927 | struct zfcp_fsf_req *req = NULL; |
985 | 928 | ||
986 | spin_lock(&adapter->req_q.lock); | 929 | spin_lock(&adapter->req_q_lock); |
987 | if (!atomic_read(&adapter->req_q.count)) | 930 | if (!zfcp_fsf_sbal_available(adapter)) |
988 | goto out; | 931 | goto out; |
989 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, | 932 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, |
990 | req_flags, adapter->pool.fsf_req_abort); | 933 | req_flags, adapter->pool.fsf_req_abort); |
@@ -1013,7 +956,7 @@ out_error_free: | |||
1013 | zfcp_fsf_req_free(req); | 956 | zfcp_fsf_req_free(req); |
1014 | req = NULL; | 957 | req = NULL; |
1015 | out: | 958 | out: |
1016 | spin_unlock(&adapter->req_q.lock); | 959 | spin_unlock(&adapter->req_q_lock); |
1017 | return req; | 960 | return req; |
1018 | } | 961 | } |
1019 | 962 | ||
@@ -1021,7 +964,6 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | |||
1021 | { | 964 | { |
1022 | struct zfcp_adapter *adapter = req->adapter; | 965 | struct zfcp_adapter *adapter = req->adapter; |
1023 | struct zfcp_send_ct *send_ct = req->data; | 966 | struct zfcp_send_ct *send_ct = req->data; |
1024 | struct zfcp_port *port = send_ct->port; | ||
1025 | struct fsf_qtcb_header *header = &req->qtcb->header; | 967 | struct fsf_qtcb_header *header = &req->qtcb->header; |
1026 | 968 | ||
1027 | send_ct->status = -EINVAL; | 969 | send_ct->status = -EINVAL; |
@@ -1040,17 +982,14 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | |||
1040 | case FSF_ADAPTER_STATUS_AVAILABLE: | 982 | case FSF_ADAPTER_STATUS_AVAILABLE: |
1041 | switch (header->fsf_status_qual.word[0]){ | 983 | switch (header->fsf_status_qual.word[0]){ |
1042 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 984 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
1043 | zfcp_test_link(port); | ||
1044 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 985 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
1045 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 986 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1046 | break; | 987 | break; |
1047 | } | 988 | } |
1048 | break; | 989 | break; |
1049 | case FSF_ACCESS_DENIED: | 990 | case FSF_ACCESS_DENIED: |
1050 | zfcp_fsf_access_denied_port(req, port); | ||
1051 | break; | 991 | break; |
1052 | case FSF_PORT_BOXED: | 992 | case FSF_PORT_BOXED: |
1053 | zfcp_erp_port_boxed(port, 49, req); | ||
1054 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 993 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
1055 | ZFCP_STATUS_FSFREQ_RETRY; | 994 | ZFCP_STATUS_FSFREQ_RETRY; |
1056 | break; | 995 | break; |
@@ -1101,12 +1040,12 @@ static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req, | |||
1101 | int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | 1040 | int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, |
1102 | struct zfcp_erp_action *erp_action) | 1041 | struct zfcp_erp_action *erp_action) |
1103 | { | 1042 | { |
1104 | struct zfcp_port *port = ct->port; | 1043 | struct zfcp_wka_port *wka_port = ct->wka_port; |
1105 | struct zfcp_adapter *adapter = port->adapter; | 1044 | struct zfcp_adapter *adapter = wka_port->adapter; |
1106 | struct zfcp_fsf_req *req; | 1045 | struct zfcp_fsf_req *req; |
1107 | int ret = -EIO; | 1046 | int ret = -EIO; |
1108 | 1047 | ||
1109 | spin_lock_bh(&adapter->req_q.lock); | 1048 | spin_lock_bh(&adapter->req_q_lock); |
1110 | if (zfcp_fsf_req_sbal_get(adapter)) | 1049 | if (zfcp_fsf_req_sbal_get(adapter)) |
1111 | goto out; | 1050 | goto out; |
1112 | 1051 | ||
@@ -1123,7 +1062,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | |||
1123 | goto failed_send; | 1062 | goto failed_send; |
1124 | 1063 | ||
1125 | req->handler = zfcp_fsf_send_ct_handler; | 1064 | req->handler = zfcp_fsf_send_ct_handler; |
1126 | req->qtcb->header.port_handle = port->handle; | 1065 | req->qtcb->header.port_handle = wka_port->handle; |
1127 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; | 1066 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; |
1128 | req->qtcb->bottom.support.timeout = ct->timeout; | 1067 | req->qtcb->bottom.support.timeout = ct->timeout; |
1129 | req->data = ct; | 1068 | req->data = ct; |
@@ -1148,7 +1087,7 @@ failed_send: | |||
1148 | if (erp_action) | 1087 | if (erp_action) |
1149 | erp_action->fsf_req = NULL; | 1088 | erp_action->fsf_req = NULL; |
1150 | out: | 1089 | out: |
1151 | spin_unlock_bh(&adapter->req_q.lock); | 1090 | spin_unlock_bh(&adapter->req_q_lock); |
1152 | return ret; | 1091 | return ret; |
1153 | } | 1092 | } |
1154 | 1093 | ||
@@ -1218,8 +1157,8 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1218 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 1157 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
1219 | return -EBUSY; | 1158 | return -EBUSY; |
1220 | 1159 | ||
1221 | spin_lock(&adapter->req_q.lock); | 1160 | spin_lock(&adapter->req_q_lock); |
1222 | if (!atomic_read(&adapter->req_q.count)) | 1161 | if (!zfcp_fsf_sbal_available(adapter)) |
1223 | goto out; | 1162 | goto out; |
1224 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, | 1163 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, |
1225 | ZFCP_REQ_AUTO_CLEANUP, NULL); | 1164 | ZFCP_REQ_AUTO_CLEANUP, NULL); |
@@ -1228,8 +1167,8 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1228 | goto out; | 1167 | goto out; |
1229 | } | 1168 | } |
1230 | 1169 | ||
1231 | ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, | 1170 | ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, 2); |
1232 | FSF_MAX_SBALS_PER_ELS_REQ); | 1171 | |
1233 | if (ret) | 1172 | if (ret) |
1234 | goto failed_send; | 1173 | goto failed_send; |
1235 | 1174 | ||
@@ -1252,19 +1191,19 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1252 | failed_send: | 1191 | failed_send: |
1253 | zfcp_fsf_req_free(req); | 1192 | zfcp_fsf_req_free(req); |
1254 | out: | 1193 | out: |
1255 | spin_unlock(&adapter->req_q.lock); | 1194 | spin_unlock(&adapter->req_q_lock); |
1256 | return ret; | 1195 | return ret; |
1257 | } | 1196 | } |
1258 | 1197 | ||
1259 | int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | 1198 | int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) |
1260 | { | 1199 | { |
1261 | volatile struct qdio_buffer_element *sbale; | 1200 | struct qdio_buffer_element *sbale; |
1262 | struct zfcp_fsf_req *req; | 1201 | struct zfcp_fsf_req *req; |
1263 | struct zfcp_adapter *adapter = erp_action->adapter; | 1202 | struct zfcp_adapter *adapter = erp_action->adapter; |
1264 | int retval = -EIO; | 1203 | int retval = -EIO; |
1265 | 1204 | ||
1266 | spin_lock_bh(&adapter->req_q.lock); | 1205 | spin_lock_bh(&adapter->req_q_lock); |
1267 | if (!atomic_read(&adapter->req_q.count)) | 1206 | if (!zfcp_fsf_sbal_available(adapter)) |
1268 | goto out; | 1207 | goto out; |
1269 | req = zfcp_fsf_req_create(adapter, | 1208 | req = zfcp_fsf_req_create(adapter, |
1270 | FSF_QTCB_EXCHANGE_CONFIG_DATA, | 1209 | FSF_QTCB_EXCHANGE_CONFIG_DATA, |
@@ -1295,18 +1234,18 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1295 | erp_action->fsf_req = NULL; | 1234 | erp_action->fsf_req = NULL; |
1296 | } | 1235 | } |
1297 | out: | 1236 | out: |
1298 | spin_unlock_bh(&adapter->req_q.lock); | 1237 | spin_unlock_bh(&adapter->req_q_lock); |
1299 | return retval; | 1238 | return retval; |
1300 | } | 1239 | } |
1301 | 1240 | ||
1302 | int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, | 1241 | int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, |
1303 | struct fsf_qtcb_bottom_config *data) | 1242 | struct fsf_qtcb_bottom_config *data) |
1304 | { | 1243 | { |
1305 | volatile struct qdio_buffer_element *sbale; | 1244 | struct qdio_buffer_element *sbale; |
1306 | struct zfcp_fsf_req *req = NULL; | 1245 | struct zfcp_fsf_req *req = NULL; |
1307 | int retval = -EIO; | 1246 | int retval = -EIO; |
1308 | 1247 | ||
1309 | spin_lock_bh(&adapter->req_q.lock); | 1248 | spin_lock_bh(&adapter->req_q_lock); |
1310 | if (zfcp_fsf_req_sbal_get(adapter)) | 1249 | if (zfcp_fsf_req_sbal_get(adapter)) |
1311 | goto out; | 1250 | goto out; |
1312 | 1251 | ||
@@ -1334,7 +1273,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, | |||
1334 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | 1273 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); |
1335 | retval = zfcp_fsf_req_send(req); | 1274 | retval = zfcp_fsf_req_send(req); |
1336 | out: | 1275 | out: |
1337 | spin_unlock_bh(&adapter->req_q.lock); | 1276 | spin_unlock_bh(&adapter->req_q_lock); |
1338 | if (!retval) | 1277 | if (!retval) |
1339 | wait_event(req->completion_wq, | 1278 | wait_event(req->completion_wq, |
1340 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | 1279 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); |
@@ -1351,7 +1290,7 @@ out: | |||
1351 | */ | 1290 | */ |
1352 | int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) | 1291 | int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) |
1353 | { | 1292 | { |
1354 | volatile struct qdio_buffer_element *sbale; | 1293 | struct qdio_buffer_element *sbale; |
1355 | struct zfcp_fsf_req *req; | 1294 | struct zfcp_fsf_req *req; |
1356 | struct zfcp_adapter *adapter = erp_action->adapter; | 1295 | struct zfcp_adapter *adapter = erp_action->adapter; |
1357 | int retval = -EIO; | 1296 | int retval = -EIO; |
@@ -1359,8 +1298,8 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) | |||
1359 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) | 1298 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) |
1360 | return -EOPNOTSUPP; | 1299 | return -EOPNOTSUPP; |
1361 | 1300 | ||
1362 | spin_lock_bh(&adapter->req_q.lock); | 1301 | spin_lock_bh(&adapter->req_q_lock); |
1363 | if (!atomic_read(&adapter->req_q.count)) | 1302 | if (!zfcp_fsf_sbal_available(adapter)) |
1364 | goto out; | 1303 | goto out; |
1365 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, | 1304 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, |
1366 | ZFCP_REQ_AUTO_CLEANUP, | 1305 | ZFCP_REQ_AUTO_CLEANUP, |
@@ -1385,7 +1324,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) | |||
1385 | erp_action->fsf_req = NULL; | 1324 | erp_action->fsf_req = NULL; |
1386 | } | 1325 | } |
1387 | out: | 1326 | out: |
1388 | spin_unlock_bh(&adapter->req_q.lock); | 1327 | spin_unlock_bh(&adapter->req_q_lock); |
1389 | return retval; | 1328 | return retval; |
1390 | } | 1329 | } |
1391 | 1330 | ||
@@ -1398,15 +1337,15 @@ out: | |||
1398 | int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, | 1337 | int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, |
1399 | struct fsf_qtcb_bottom_port *data) | 1338 | struct fsf_qtcb_bottom_port *data) |
1400 | { | 1339 | { |
1401 | volatile struct qdio_buffer_element *sbale; | 1340 | struct qdio_buffer_element *sbale; |
1402 | struct zfcp_fsf_req *req = NULL; | 1341 | struct zfcp_fsf_req *req = NULL; |
1403 | int retval = -EIO; | 1342 | int retval = -EIO; |
1404 | 1343 | ||
1405 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) | 1344 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) |
1406 | return -EOPNOTSUPP; | 1345 | return -EOPNOTSUPP; |
1407 | 1346 | ||
1408 | spin_lock_bh(&adapter->req_q.lock); | 1347 | spin_lock_bh(&adapter->req_q_lock); |
1409 | if (!atomic_read(&adapter->req_q.count)) | 1348 | if (!zfcp_fsf_sbal_available(adapter)) |
1410 | goto out; | 1349 | goto out; |
1411 | 1350 | ||
1412 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, | 1351 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, |
@@ -1427,7 +1366,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, | |||
1427 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | 1366 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); |
1428 | retval = zfcp_fsf_req_send(req); | 1367 | retval = zfcp_fsf_req_send(req); |
1429 | out: | 1368 | out: |
1430 | spin_unlock_bh(&adapter->req_q.lock); | 1369 | spin_unlock_bh(&adapter->req_q_lock); |
1431 | if (!retval) | 1370 | if (!retval) |
1432 | wait_event(req->completion_wq, | 1371 | wait_event(req->completion_wq, |
1433 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | 1372 | req->status & ZFCP_STATUS_FSFREQ_COMPLETED); |
@@ -1443,7 +1382,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1443 | struct fsf_plogi *plogi; | 1382 | struct fsf_plogi *plogi; |
1444 | 1383 | ||
1445 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 1384 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
1446 | goto skip_fsfstatus; | 1385 | return; |
1447 | 1386 | ||
1448 | switch (header->fsf_status) { | 1387 | switch (header->fsf_status) { |
1449 | case FSF_PORT_ALREADY_OPEN: | 1388 | case FSF_PORT_ALREADY_OPEN: |
@@ -1453,9 +1392,9 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1453 | break; | 1392 | break; |
1454 | case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: | 1393 | case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: |
1455 | dev_warn(&req->adapter->ccw_device->dev, | 1394 | dev_warn(&req->adapter->ccw_device->dev, |
1456 | "The adapter is out of resources. The remote port " | 1395 | "Not enough FCP adapter resources to open " |
1457 | "0x%016Lx could not be opened, disabling it.\n", | 1396 | "remote port 0x%016Lx\n", |
1458 | port->wwpn); | 1397 | (unsigned long long)port->wwpn); |
1459 | zfcp_erp_port_failed(port, 31, req); | 1398 | zfcp_erp_port_failed(port, 31, req); |
1460 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1399 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1461 | break; | 1400 | break; |
@@ -1467,8 +1406,8 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1467 | break; | 1406 | break; |
1468 | case FSF_SQ_NO_RETRY_POSSIBLE: | 1407 | case FSF_SQ_NO_RETRY_POSSIBLE: |
1469 | dev_warn(&req->adapter->ccw_device->dev, | 1408 | dev_warn(&req->adapter->ccw_device->dev, |
1470 | "The remote port 0x%016Lx could not be " | 1409 | "Remote port 0x%016Lx could not be opened\n", |
1471 | "opened. Disabling it.\n", port->wwpn); | 1410 | (unsigned long long)port->wwpn); |
1472 | zfcp_erp_port_failed(port, 32, req); | 1411 | zfcp_erp_port_failed(port, 32, req); |
1473 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1412 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1474 | break; | 1413 | break; |
@@ -1496,9 +1435,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1496 | * another GID_PN straight after a port has been opened. | 1435 | * another GID_PN straight after a port has been opened. |
1497 | * Alternately, an ADISC/PDISC ELS should suffice, as well. | 1436 | * Alternately, an ADISC/PDISC ELS should suffice, as well. |
1498 | */ | 1437 | */ |
1499 | if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN) | ||
1500 | break; | ||
1501 | |||
1502 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; | 1438 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; |
1503 | if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { | 1439 | if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { |
1504 | if (plogi->serv_param.wwpn != port->wwpn) | 1440 | if (plogi->serv_param.wwpn != port->wwpn) |
@@ -1514,9 +1450,6 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1514 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1450 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1515 | break; | 1451 | break; |
1516 | } | 1452 | } |
1517 | |||
1518 | skip_fsfstatus: | ||
1519 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &port->status); | ||
1520 | } | 1453 | } |
1521 | 1454 | ||
1522 | /** | 1455 | /** |
@@ -1526,12 +1459,12 @@ skip_fsfstatus: | |||
1526 | */ | 1459 | */ |
1527 | int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | 1460 | int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) |
1528 | { | 1461 | { |
1529 | volatile struct qdio_buffer_element *sbale; | 1462 | struct qdio_buffer_element *sbale; |
1530 | struct zfcp_adapter *adapter = erp_action->adapter; | 1463 | struct zfcp_adapter *adapter = erp_action->adapter; |
1531 | struct zfcp_fsf_req *req; | 1464 | struct zfcp_fsf_req *req; |
1532 | int retval = -EIO; | 1465 | int retval = -EIO; |
1533 | 1466 | ||
1534 | spin_lock_bh(&adapter->req_q.lock); | 1467 | spin_lock_bh(&adapter->req_q_lock); |
1535 | if (zfcp_fsf_req_sbal_get(adapter)) | 1468 | if (zfcp_fsf_req_sbal_get(adapter)) |
1536 | goto out; | 1469 | goto out; |
1537 | 1470 | ||
@@ -1553,7 +1486,6 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | |||
1553 | req->data = erp_action->port; | 1486 | req->data = erp_action->port; |
1554 | req->erp_action = erp_action; | 1487 | req->erp_action = erp_action; |
1555 | erp_action->fsf_req = req; | 1488 | erp_action->fsf_req = req; |
1556 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status); | ||
1557 | 1489 | ||
1558 | zfcp_fsf_start_erp_timer(req); | 1490 | zfcp_fsf_start_erp_timer(req); |
1559 | retval = zfcp_fsf_req_send(req); | 1491 | retval = zfcp_fsf_req_send(req); |
@@ -1562,7 +1494,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | |||
1562 | erp_action->fsf_req = NULL; | 1494 | erp_action->fsf_req = NULL; |
1563 | } | 1495 | } |
1564 | out: | 1496 | out: |
1565 | spin_unlock_bh(&adapter->req_q.lock); | 1497 | spin_unlock_bh(&adapter->req_q_lock); |
1566 | return retval; | 1498 | return retval; |
1567 | } | 1499 | } |
1568 | 1500 | ||
@@ -1571,7 +1503,7 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req) | |||
1571 | struct zfcp_port *port = req->data; | 1503 | struct zfcp_port *port = req->data; |
1572 | 1504 | ||
1573 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 1505 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
1574 | goto skip_fsfstatus; | 1506 | return; |
1575 | 1507 | ||
1576 | switch (req->qtcb->header.fsf_status) { | 1508 | switch (req->qtcb->header.fsf_status) { |
1577 | case FSF_PORT_HANDLE_NOT_VALID: | 1509 | case FSF_PORT_HANDLE_NOT_VALID: |
@@ -1586,9 +1518,6 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req) | |||
1586 | ZFCP_CLEAR); | 1518 | ZFCP_CLEAR); |
1587 | break; | 1519 | break; |
1588 | } | 1520 | } |
1589 | |||
1590 | skip_fsfstatus: | ||
1591 | atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &port->status); | ||
1592 | } | 1521 | } |
1593 | 1522 | ||
1594 | /** | 1523 | /** |
@@ -1598,12 +1527,12 @@ skip_fsfstatus: | |||
1598 | */ | 1527 | */ |
1599 | int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) | 1528 | int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) |
1600 | { | 1529 | { |
1601 | volatile struct qdio_buffer_element *sbale; | 1530 | struct qdio_buffer_element *sbale; |
1602 | struct zfcp_adapter *adapter = erp_action->adapter; | 1531 | struct zfcp_adapter *adapter = erp_action->adapter; |
1603 | struct zfcp_fsf_req *req; | 1532 | struct zfcp_fsf_req *req; |
1604 | int retval = -EIO; | 1533 | int retval = -EIO; |
1605 | 1534 | ||
1606 | spin_lock_bh(&adapter->req_q.lock); | 1535 | spin_lock_bh(&adapter->req_q_lock); |
1607 | if (zfcp_fsf_req_sbal_get(adapter)) | 1536 | if (zfcp_fsf_req_sbal_get(adapter)) |
1608 | goto out; | 1537 | goto out; |
1609 | 1538 | ||
@@ -1624,7 +1553,6 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) | |||
1624 | req->erp_action = erp_action; | 1553 | req->erp_action = erp_action; |
1625 | req->qtcb->header.port_handle = erp_action->port->handle; | 1554 | req->qtcb->header.port_handle = erp_action->port->handle; |
1626 | erp_action->fsf_req = req; | 1555 | erp_action->fsf_req = req; |
1627 | atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status); | ||
1628 | 1556 | ||
1629 | zfcp_fsf_start_erp_timer(req); | 1557 | zfcp_fsf_start_erp_timer(req); |
1630 | retval = zfcp_fsf_req_send(req); | 1558 | retval = zfcp_fsf_req_send(req); |
@@ -1633,7 +1561,131 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) | |||
1633 | erp_action->fsf_req = NULL; | 1561 | erp_action->fsf_req = NULL; |
1634 | } | 1562 | } |
1635 | out: | 1563 | out: |
1636 | spin_unlock_bh(&adapter->req_q.lock); | 1564 | spin_unlock_bh(&adapter->req_q_lock); |
1565 | return retval; | ||
1566 | } | ||
1567 | |||
1568 | static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) | ||
1569 | { | ||
1570 | struct zfcp_wka_port *wka_port = req->data; | ||
1571 | struct fsf_qtcb_header *header = &req->qtcb->header; | ||
1572 | |||
1573 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) { | ||
1574 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
1575 | goto out; | ||
1576 | } | ||
1577 | |||
1578 | switch (header->fsf_status) { | ||
1579 | case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: | ||
1580 | dev_warn(&req->adapter->ccw_device->dev, | ||
1581 | "Opening WKA port 0x%x failed\n", wka_port->d_id); | ||
1582 | case FSF_ADAPTER_STATUS_AVAILABLE: | ||
1583 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | ||
1584 | case FSF_ACCESS_DENIED: | ||
1585 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
1586 | break; | ||
1587 | case FSF_PORT_ALREADY_OPEN: | ||
1588 | case FSF_GOOD: | ||
1589 | wka_port->handle = header->port_handle; | ||
1590 | wka_port->status = ZFCP_WKA_PORT_ONLINE; | ||
1591 | } | ||
1592 | out: | ||
1593 | wake_up(&wka_port->completion_wq); | ||
1594 | } | ||
1595 | |||
1596 | /** | ||
1597 | * zfcp_fsf_open_wka_port - create and send open wka-port request | ||
1598 | * @wka_port: pointer to struct zfcp_wka_port | ||
1599 | * Returns: 0 on success, error otherwise | ||
1600 | */ | ||
1601 | int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port) | ||
1602 | { | ||
1603 | struct qdio_buffer_element *sbale; | ||
1604 | struct zfcp_adapter *adapter = wka_port->adapter; | ||
1605 | struct zfcp_fsf_req *req; | ||
1606 | int retval = -EIO; | ||
1607 | |||
1608 | spin_lock_bh(&adapter->req_q_lock); | ||
1609 | if (zfcp_fsf_req_sbal_get(adapter)) | ||
1610 | goto out; | ||
1611 | |||
1612 | req = zfcp_fsf_req_create(adapter, | ||
1613 | FSF_QTCB_OPEN_PORT_WITH_DID, | ||
1614 | ZFCP_REQ_AUTO_CLEANUP, | ||
1615 | adapter->pool.fsf_req_erp); | ||
1616 | if (unlikely(IS_ERR(req))) { | ||
1617 | retval = PTR_ERR(req); | ||
1618 | goto out; | ||
1619 | } | ||
1620 | |||
1621 | sbale = zfcp_qdio_sbale_req(req); | ||
1622 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | ||
1623 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | ||
1624 | |||
1625 | req->handler = zfcp_fsf_open_wka_port_handler; | ||
1626 | req->qtcb->bottom.support.d_id = wka_port->d_id; | ||
1627 | req->data = wka_port; | ||
1628 | |||
1629 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | ||
1630 | retval = zfcp_fsf_req_send(req); | ||
1631 | if (retval) | ||
1632 | zfcp_fsf_req_free(req); | ||
1633 | out: | ||
1634 | spin_unlock_bh(&adapter->req_q_lock); | ||
1635 | return retval; | ||
1636 | } | ||
1637 | |||
1638 | static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) | ||
1639 | { | ||
1640 | struct zfcp_wka_port *wka_port = req->data; | ||
1641 | |||
1642 | if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) { | ||
1643 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | ||
1644 | zfcp_erp_adapter_reopen(wka_port->adapter, 0, 84, req); | ||
1645 | } | ||
1646 | |||
1647 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | ||
1648 | wake_up(&wka_port->completion_wq); | ||
1649 | } | ||
1650 | |||
1651 | /** | ||
1652 | * zfcp_fsf_close_wka_port - create and send close wka port request | ||
1653 | * @erp_action: pointer to struct zfcp_erp_action | ||
1654 | * Returns: 0 on success, error otherwise | ||
1655 | */ | ||
1656 | int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port) | ||
1657 | { | ||
1658 | struct qdio_buffer_element *sbale; | ||
1659 | struct zfcp_adapter *adapter = wka_port->adapter; | ||
1660 | struct zfcp_fsf_req *req; | ||
1661 | int retval = -EIO; | ||
1662 | |||
1663 | spin_lock_bh(&adapter->req_q_lock); | ||
1664 | if (zfcp_fsf_req_sbal_get(adapter)) | ||
1665 | goto out; | ||
1666 | |||
1667 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, | ||
1668 | ZFCP_REQ_AUTO_CLEANUP, | ||
1669 | adapter->pool.fsf_req_erp); | ||
1670 | if (unlikely(IS_ERR(req))) { | ||
1671 | retval = PTR_ERR(req); | ||
1672 | goto out; | ||
1673 | } | ||
1674 | |||
1675 | sbale = zfcp_qdio_sbale_req(req); | ||
1676 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | ||
1677 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | ||
1678 | |||
1679 | req->handler = zfcp_fsf_close_wka_port_handler; | ||
1680 | req->data = wka_port; | ||
1681 | req->qtcb->header.port_handle = wka_port->handle; | ||
1682 | |||
1683 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | ||
1684 | retval = zfcp_fsf_req_send(req); | ||
1685 | if (retval) | ||
1686 | zfcp_fsf_req_free(req); | ||
1687 | out: | ||
1688 | spin_unlock_bh(&adapter->req_q_lock); | ||
1637 | return retval; | 1689 | return retval; |
1638 | } | 1690 | } |
1639 | 1691 | ||
@@ -1695,12 +1747,12 @@ skip_fsfstatus: | |||
1695 | */ | 1747 | */ |
1696 | int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) | 1748 | int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) |
1697 | { | 1749 | { |
1698 | volatile struct qdio_buffer_element *sbale; | 1750 | struct qdio_buffer_element *sbale; |
1699 | struct zfcp_adapter *adapter = erp_action->adapter; | 1751 | struct zfcp_adapter *adapter = erp_action->adapter; |
1700 | struct zfcp_fsf_req *req; | 1752 | struct zfcp_fsf_req *req; |
1701 | int retval = -EIO; | 1753 | int retval = -EIO; |
1702 | 1754 | ||
1703 | spin_lock_bh(&adapter->req_q.lock); | 1755 | spin_lock_bh(&adapter->req_q_lock); |
1704 | if (zfcp_fsf_req_sbal_get(adapter)) | 1756 | if (zfcp_fsf_req_sbal_get(adapter)) |
1705 | goto out; | 1757 | goto out; |
1706 | 1758 | ||
@@ -1731,7 +1783,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) | |||
1731 | erp_action->fsf_req = NULL; | 1783 | erp_action->fsf_req = NULL; |
1732 | } | 1784 | } |
1733 | out: | 1785 | out: |
1734 | spin_unlock_bh(&adapter->req_q.lock); | 1786 | spin_unlock_bh(&adapter->req_q_lock); |
1735 | return retval; | 1787 | return retval; |
1736 | } | 1788 | } |
1737 | 1789 | ||
@@ -1746,7 +1798,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) | |||
1746 | int exclusive, readwrite; | 1798 | int exclusive, readwrite; |
1747 | 1799 | ||
1748 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 1800 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
1749 | goto skip_fsfstatus; | 1801 | return; |
1750 | 1802 | ||
1751 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | | 1803 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | |
1752 | ZFCP_STATUS_COMMON_ACCESS_BOXED | | 1804 | ZFCP_STATUS_COMMON_ACCESS_BOXED | |
@@ -1774,14 +1826,12 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) | |||
1774 | case FSF_LUN_SHARING_VIOLATION: | 1826 | case FSF_LUN_SHARING_VIOLATION: |
1775 | if (header->fsf_status_qual.word[0]) | 1827 | if (header->fsf_status_qual.word[0]) |
1776 | dev_warn(&adapter->ccw_device->dev, | 1828 | dev_warn(&adapter->ccw_device->dev, |
1777 | "FCP-LUN 0x%Lx at the remote port " | 1829 | "LUN 0x%Lx on port 0x%Lx is already in " |
1778 | "with WWPN 0x%Lx " | 1830 | "use by CSS%d, MIF Image ID %x\n", |
1779 | "connected to the adapter " | 1831 | (unsigned long long)unit->fcp_lun, |
1780 | "is already in use in LPAR%d, CSS%d.\n", | 1832 | (unsigned long long)unit->port->wwpn, |
1781 | unit->fcp_lun, | 1833 | queue_designator->cssid, |
1782 | unit->port->wwpn, | 1834 | queue_designator->hla); |
1783 | queue_designator->hla, | ||
1784 | queue_designator->cssid); | ||
1785 | else | 1835 | else |
1786 | zfcp_act_eval_err(adapter, | 1836 | zfcp_act_eval_err(adapter, |
1787 | header->fsf_status_qual.word[2]); | 1837 | header->fsf_status_qual.word[2]); |
@@ -1792,9 +1842,10 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) | |||
1792 | break; | 1842 | break; |
1793 | case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED: | 1843 | case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED: |
1794 | dev_warn(&adapter->ccw_device->dev, | 1844 | dev_warn(&adapter->ccw_device->dev, |
1795 | "The adapter ran out of resources. There is no " | 1845 | "No handle is available for LUN " |
1796 | "handle available for unit 0x%016Lx on port 0x%016Lx.", | 1846 | "0x%016Lx on port 0x%016Lx\n", |
1797 | unit->fcp_lun, unit->port->wwpn); | 1847 | (unsigned long long)unit->fcp_lun, |
1848 | (unsigned long long)unit->port->wwpn); | ||
1798 | zfcp_erp_unit_failed(unit, 34, req); | 1849 | zfcp_erp_unit_failed(unit, 34, req); |
1799 | /* fall through */ | 1850 | /* fall through */ |
1800 | case FSF_INVALID_COMMAND_OPTION: | 1851 | case FSF_INVALID_COMMAND_OPTION: |
@@ -1831,26 +1882,29 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) | |||
1831 | atomic_set_mask(ZFCP_STATUS_UNIT_READONLY, | 1882 | atomic_set_mask(ZFCP_STATUS_UNIT_READONLY, |
1832 | &unit->status); | 1883 | &unit->status); |
1833 | dev_info(&adapter->ccw_device->dev, | 1884 | dev_info(&adapter->ccw_device->dev, |
1834 | "Read-only access for unit 0x%016Lx " | 1885 | "SCSI device at LUN 0x%016Lx on port " |
1835 | "on port 0x%016Lx.\n", | 1886 | "0x%016Lx opened read-only\n", |
1836 | unit->fcp_lun, unit->port->wwpn); | 1887 | (unsigned long long)unit->fcp_lun, |
1888 | (unsigned long long)unit->port->wwpn); | ||
1837 | } | 1889 | } |
1838 | 1890 | ||
1839 | if (exclusive && !readwrite) { | 1891 | if (exclusive && !readwrite) { |
1840 | dev_err(&adapter->ccw_device->dev, | 1892 | dev_err(&adapter->ccw_device->dev, |
1841 | "Exclusive access of read-only unit " | 1893 | "Exclusive read-only access not " |
1842 | "0x%016Lx on port 0x%016Lx not " | 1894 | "supported (unit 0x%016Lx, " |
1843 | "supported, disabling unit.\n", | 1895 | "port 0x%016Lx)\n", |
1844 | unit->fcp_lun, unit->port->wwpn); | 1896 | (unsigned long long)unit->fcp_lun, |
1897 | (unsigned long long)unit->port->wwpn); | ||
1845 | zfcp_erp_unit_failed(unit, 35, req); | 1898 | zfcp_erp_unit_failed(unit, 35, req); |
1846 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1899 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1847 | zfcp_erp_unit_shutdown(unit, 0, 80, req); | 1900 | zfcp_erp_unit_shutdown(unit, 0, 80, req); |
1848 | } else if (!exclusive && readwrite) { | 1901 | } else if (!exclusive && readwrite) { |
1849 | dev_err(&adapter->ccw_device->dev, | 1902 | dev_err(&adapter->ccw_device->dev, |
1850 | "Shared access of read-write unit " | 1903 | "Shared read-write access not " |
1851 | "0x%016Lx on port 0x%016Lx not " | 1904 | "supported (unit 0x%016Lx, port " |
1852 | "supported, disabling unit.\n", | 1905 | "0x%016Lx\n)", |
1853 | unit->fcp_lun, unit->port->wwpn); | 1906 | (unsigned long long)unit->fcp_lun, |
1907 | (unsigned long long)unit->port->wwpn); | ||
1854 | zfcp_erp_unit_failed(unit, 36, req); | 1908 | zfcp_erp_unit_failed(unit, 36, req); |
1855 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1909 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1856 | zfcp_erp_unit_shutdown(unit, 0, 81, req); | 1910 | zfcp_erp_unit_shutdown(unit, 0, 81, req); |
@@ -1858,9 +1912,6 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) | |||
1858 | } | 1912 | } |
1859 | break; | 1913 | break; |
1860 | } | 1914 | } |
1861 | |||
1862 | skip_fsfstatus: | ||
1863 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING, &unit->status); | ||
1864 | } | 1915 | } |
1865 | 1916 | ||
1866 | /** | 1917 | /** |
@@ -1870,12 +1921,12 @@ skip_fsfstatus: | |||
1870 | */ | 1921 | */ |
1871 | int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | 1922 | int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) |
1872 | { | 1923 | { |
1873 | volatile struct qdio_buffer_element *sbale; | 1924 | struct qdio_buffer_element *sbale; |
1874 | struct zfcp_adapter *adapter = erp_action->adapter; | 1925 | struct zfcp_adapter *adapter = erp_action->adapter; |
1875 | struct zfcp_fsf_req *req; | 1926 | struct zfcp_fsf_req *req; |
1876 | int retval = -EIO; | 1927 | int retval = -EIO; |
1877 | 1928 | ||
1878 | spin_lock_bh(&adapter->req_q.lock); | 1929 | spin_lock_bh(&adapter->req_q_lock); |
1879 | if (zfcp_fsf_req_sbal_get(adapter)) | 1930 | if (zfcp_fsf_req_sbal_get(adapter)) |
1880 | goto out; | 1931 | goto out; |
1881 | 1932 | ||
@@ -1901,8 +1952,6 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | |||
1901 | if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) | 1952 | if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) |
1902 | req->qtcb->bottom.support.option = FSF_OPEN_LUN_SUPPRESS_BOXING; | 1953 | req->qtcb->bottom.support.option = FSF_OPEN_LUN_SUPPRESS_BOXING; |
1903 | 1954 | ||
1904 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); | ||
1905 | |||
1906 | zfcp_fsf_start_erp_timer(req); | 1955 | zfcp_fsf_start_erp_timer(req); |
1907 | retval = zfcp_fsf_req_send(req); | 1956 | retval = zfcp_fsf_req_send(req); |
1908 | if (retval) { | 1957 | if (retval) { |
@@ -1910,7 +1959,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | |||
1910 | erp_action->fsf_req = NULL; | 1959 | erp_action->fsf_req = NULL; |
1911 | } | 1960 | } |
1912 | out: | 1961 | out: |
1913 | spin_unlock_bh(&adapter->req_q.lock); | 1962 | spin_unlock_bh(&adapter->req_q_lock); |
1914 | return retval; | 1963 | return retval; |
1915 | } | 1964 | } |
1916 | 1965 | ||
@@ -1919,7 +1968,7 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req) | |||
1919 | struct zfcp_unit *unit = req->data; | 1968 | struct zfcp_unit *unit = req->data; |
1920 | 1969 | ||
1921 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 1970 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
1922 | goto skip_fsfstatus; | 1971 | return; |
1923 | 1972 | ||
1924 | switch (req->qtcb->header.fsf_status) { | 1973 | switch (req->qtcb->header.fsf_status) { |
1925 | case FSF_PORT_HANDLE_NOT_VALID: | 1974 | case FSF_PORT_HANDLE_NOT_VALID: |
@@ -1949,8 +1998,6 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req) | |||
1949 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); | 1998 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); |
1950 | break; | 1999 | break; |
1951 | } | 2000 | } |
1952 | skip_fsfstatus: | ||
1953 | atomic_clear_mask(ZFCP_STATUS_COMMON_CLOSING, &unit->status); | ||
1954 | } | 2001 | } |
1955 | 2002 | ||
1956 | /** | 2003 | /** |
@@ -1960,12 +2007,12 @@ skip_fsfstatus: | |||
1960 | */ | 2007 | */ |
1961 | int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) | 2008 | int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) |
1962 | { | 2009 | { |
1963 | volatile struct qdio_buffer_element *sbale; | 2010 | struct qdio_buffer_element *sbale; |
1964 | struct zfcp_adapter *adapter = erp_action->adapter; | 2011 | struct zfcp_adapter *adapter = erp_action->adapter; |
1965 | struct zfcp_fsf_req *req; | 2012 | struct zfcp_fsf_req *req; |
1966 | int retval = -EIO; | 2013 | int retval = -EIO; |
1967 | 2014 | ||
1968 | spin_lock_bh(&adapter->req_q.lock); | 2015 | spin_lock_bh(&adapter->req_q_lock); |
1969 | if (zfcp_fsf_req_sbal_get(adapter)) | 2016 | if (zfcp_fsf_req_sbal_get(adapter)) |
1970 | goto out; | 2017 | goto out; |
1971 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, | 2018 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, |
@@ -1986,7 +2033,6 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) | |||
1986 | req->data = erp_action->unit; | 2033 | req->data = erp_action->unit; |
1987 | req->erp_action = erp_action; | 2034 | req->erp_action = erp_action; |
1988 | erp_action->fsf_req = req; | 2035 | erp_action->fsf_req = req; |
1989 | atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status); | ||
1990 | 2036 | ||
1991 | zfcp_fsf_start_erp_timer(req); | 2037 | zfcp_fsf_start_erp_timer(req); |
1992 | retval = zfcp_fsf_req_send(req); | 2038 | retval = zfcp_fsf_req_send(req); |
@@ -1995,7 +2041,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) | |||
1995 | erp_action->fsf_req = NULL; | 2041 | erp_action->fsf_req = NULL; |
1996 | } | 2042 | } |
1997 | out: | 2043 | out: |
1998 | spin_unlock_bh(&adapter->req_q.lock); | 2044 | spin_unlock_bh(&adapter->req_q_lock); |
1999 | return retval; | 2045 | return retval; |
2000 | } | 2046 | } |
2001 | 2047 | ||
@@ -2156,21 +2202,21 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req) | |||
2156 | break; | 2202 | break; |
2157 | case FSF_DIRECTION_INDICATOR_NOT_VALID: | 2203 | case FSF_DIRECTION_INDICATOR_NOT_VALID: |
2158 | dev_err(&req->adapter->ccw_device->dev, | 2204 | dev_err(&req->adapter->ccw_device->dev, |
2159 | "Invalid data direction (%d) given for unit " | 2205 | "Incorrect direction %d, unit 0x%016Lx on port " |
2160 | "0x%016Lx on port 0x%016Lx, shutting down " | 2206 | "0x%016Lx closed\n", |
2161 | "adapter.\n", | ||
2162 | req->qtcb->bottom.io.data_direction, | 2207 | req->qtcb->bottom.io.data_direction, |
2163 | unit->fcp_lun, unit->port->wwpn); | 2208 | (unsigned long long)unit->fcp_lun, |
2209 | (unsigned long long)unit->port->wwpn); | ||
2164 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, req); | 2210 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, req); |
2165 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2211 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2166 | break; | 2212 | break; |
2167 | case FSF_CMND_LENGTH_NOT_VALID: | 2213 | case FSF_CMND_LENGTH_NOT_VALID: |
2168 | dev_err(&req->adapter->ccw_device->dev, | 2214 | dev_err(&req->adapter->ccw_device->dev, |
2169 | "An invalid control-data-block length field (%d) " | 2215 | "Incorrect CDB length %d, unit 0x%016Lx on " |
2170 | "was found in a command for unit 0x%016Lx on port " | 2216 | "port 0x%016Lx closed\n", |
2171 | "0x%016Lx. Shutting down adapter.\n", | ||
2172 | req->qtcb->bottom.io.fcp_cmnd_length, | 2217 | req->qtcb->bottom.io.fcp_cmnd_length, |
2173 | unit->fcp_lun, unit->port->wwpn); | 2218 | (unsigned long long)unit->fcp_lun, |
2219 | (unsigned long long)unit->port->wwpn); | ||
2174 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, req); | 2220 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, req); |
2175 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2221 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2176 | break; | 2222 | break; |
@@ -2201,6 +2247,20 @@ skip_fsfstatus: | |||
2201 | } | 2247 | } |
2202 | } | 2248 | } |
2203 | 2249 | ||
2250 | static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl) | ||
2251 | { | ||
2252 | u32 *fcp_dl_ptr; | ||
2253 | |||
2254 | /* | ||
2255 | * fcp_dl_addr = start address of fcp_cmnd structure + | ||
2256 | * size of fixed part + size of dynamically sized add_dcp_cdb field | ||
2257 | * SEE FCP-2 documentation | ||
2258 | */ | ||
2259 | fcp_dl_ptr = (u32 *) ((unsigned char *) &fcp_cmd[1] + | ||
2260 | (fcp_cmd->add_fcp_cdb_length << 2)); | ||
2261 | *fcp_dl_ptr = fcp_dl; | ||
2262 | } | ||
2263 | |||
2204 | /** | 2264 | /** |
2205 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) | 2265 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) |
2206 | * @adapter: adapter where scsi command is issued | 2266 | * @adapter: adapter where scsi command is issued |
@@ -2223,8 +2283,8 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
2223 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 2283 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
2224 | return -EBUSY; | 2284 | return -EBUSY; |
2225 | 2285 | ||
2226 | spin_lock(&adapter->req_q.lock); | 2286 | spin_lock(&adapter->req_q_lock); |
2227 | if (!atomic_read(&adapter->req_q.count)) | 2287 | if (!zfcp_fsf_sbal_available(adapter)) |
2228 | goto out; | 2288 | goto out; |
2229 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | 2289 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, |
2230 | adapter->pool.fsf_req_scsi); | 2290 | adapter->pool.fsf_req_scsi); |
@@ -2286,7 +2346,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
2286 | memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); | 2346 | memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); |
2287 | 2347 | ||
2288 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + | 2348 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + |
2289 | fcp_cmnd_iu->add_fcp_cdb_length + sizeof(fcp_dl_t); | 2349 | fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32); |
2290 | 2350 | ||
2291 | real_bytes = zfcp_qdio_sbals_from_sg(req, sbtype, | 2351 | real_bytes = zfcp_qdio_sbals_from_sg(req, sbtype, |
2292 | scsi_sglist(scsi_cmnd), | 2352 | scsi_sglist(scsi_cmnd), |
@@ -2296,10 +2356,10 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
2296 | retval = -EIO; | 2356 | retval = -EIO; |
2297 | else { | 2357 | else { |
2298 | dev_err(&adapter->ccw_device->dev, | 2358 | dev_err(&adapter->ccw_device->dev, |
2299 | "SCSI request too large. " | 2359 | "Oversize data package, unit 0x%016Lx " |
2300 | "Shutting down unit 0x%016Lx on port " | 2360 | "on port 0x%016Lx closed\n", |
2301 | "0x%016Lx.\n", unit->fcp_lun, | 2361 | (unsigned long long)unit->fcp_lun, |
2302 | unit->port->wwpn); | 2362 | (unsigned long long)unit->port->wwpn); |
2303 | zfcp_erp_unit_shutdown(unit, 0, 131, req); | 2363 | zfcp_erp_unit_shutdown(unit, 0, 131, req); |
2304 | retval = -EINVAL; | 2364 | retval = -EINVAL; |
2305 | } | 2365 | } |
@@ -2322,7 +2382,7 @@ failed_scsi_cmnd: | |||
2322 | zfcp_fsf_req_free(req); | 2382 | zfcp_fsf_req_free(req); |
2323 | scsi_cmnd->host_scribble = NULL; | 2383 | scsi_cmnd->host_scribble = NULL; |
2324 | out: | 2384 | out: |
2325 | spin_unlock(&adapter->req_q.lock); | 2385 | spin_unlock(&adapter->req_q_lock); |
2326 | return retval; | 2386 | return retval; |
2327 | } | 2387 | } |
2328 | 2388 | ||
@@ -2338,7 +2398,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, | |||
2338 | struct zfcp_unit *unit, | 2398 | struct zfcp_unit *unit, |
2339 | u8 tm_flags, int req_flags) | 2399 | u8 tm_flags, int req_flags) |
2340 | { | 2400 | { |
2341 | volatile struct qdio_buffer_element *sbale; | 2401 | struct qdio_buffer_element *sbale; |
2342 | struct zfcp_fsf_req *req = NULL; | 2402 | struct zfcp_fsf_req *req = NULL; |
2343 | struct fcp_cmnd_iu *fcp_cmnd_iu; | 2403 | struct fcp_cmnd_iu *fcp_cmnd_iu; |
2344 | 2404 | ||
@@ -2346,8 +2406,8 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, | |||
2346 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 2406 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
2347 | return NULL; | 2407 | return NULL; |
2348 | 2408 | ||
2349 | spin_lock(&adapter->req_q.lock); | 2409 | spin_lock(&adapter->req_q_lock); |
2350 | if (!atomic_read(&adapter->req_q.count)) | 2410 | if (!zfcp_fsf_sbal_available(adapter)) |
2351 | goto out; | 2411 | goto out; |
2352 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | 2412 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, |
2353 | adapter->pool.fsf_req_scsi); | 2413 | adapter->pool.fsf_req_scsi); |
@@ -2362,7 +2422,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, | |||
2362 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; | 2422 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; |
2363 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; | 2423 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; |
2364 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + | 2424 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + |
2365 | sizeof(fcp_dl_t); | 2425 | sizeof(u32); |
2366 | 2426 | ||
2367 | sbale = zfcp_qdio_sbale_req(req); | 2427 | sbale = zfcp_qdio_sbale_req(req); |
2368 | sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; | 2428 | sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; |
@@ -2379,7 +2439,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, | |||
2379 | zfcp_fsf_req_free(req); | 2439 | zfcp_fsf_req_free(req); |
2380 | req = NULL; | 2440 | req = NULL; |
2381 | out: | 2441 | out: |
2382 | spin_unlock(&adapter->req_q.lock); | 2442 | spin_unlock(&adapter->req_q_lock); |
2383 | return req; | 2443 | return req; |
2384 | } | 2444 | } |
2385 | 2445 | ||
@@ -2398,7 +2458,7 @@ static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req) | |||
2398 | struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, | 2458 | struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, |
2399 | struct zfcp_fsf_cfdc *fsf_cfdc) | 2459 | struct zfcp_fsf_cfdc *fsf_cfdc) |
2400 | { | 2460 | { |
2401 | volatile struct qdio_buffer_element *sbale; | 2461 | struct qdio_buffer_element *sbale; |
2402 | struct zfcp_fsf_req *req = NULL; | 2462 | struct zfcp_fsf_req *req = NULL; |
2403 | struct fsf_qtcb_bottom_support *bottom; | 2463 | struct fsf_qtcb_bottom_support *bottom; |
2404 | int direction, retval = -EIO, bytes; | 2464 | int direction, retval = -EIO, bytes; |
@@ -2417,7 +2477,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, | |||
2417 | return ERR_PTR(-EINVAL); | 2477 | return ERR_PTR(-EINVAL); |
2418 | } | 2478 | } |
2419 | 2479 | ||
2420 | spin_lock_bh(&adapter->req_q.lock); | 2480 | spin_lock_bh(&adapter->req_q_lock); |
2421 | if (zfcp_fsf_req_sbal_get(adapter)) | 2481 | if (zfcp_fsf_req_sbal_get(adapter)) |
2422 | goto out; | 2482 | goto out; |
2423 | 2483 | ||
@@ -2447,7 +2507,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, | |||
2447 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | 2507 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); |
2448 | retval = zfcp_fsf_req_send(req); | 2508 | retval = zfcp_fsf_req_send(req); |
2449 | out: | 2509 | out: |
2450 | spin_unlock_bh(&adapter->req_q.lock); | 2510 | spin_unlock_bh(&adapter->req_q_lock); |
2451 | 2511 | ||
2452 | if (!retval) { | 2512 | if (!retval) { |
2453 | wait_event(req->completion_wq, | 2513 | wait_event(req->completion_wq, |
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index bf94b4da0763..fd3a88777ac8 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h | |||
@@ -71,13 +71,6 @@ | |||
71 | #define FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED 0x00000041 | 71 | #define FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED 0x00000041 |
72 | #define FSF_ELS_COMMAND_REJECTED 0x00000050 | 72 | #define FSF_ELS_COMMAND_REJECTED 0x00000050 |
73 | #define FSF_GENERIC_COMMAND_REJECTED 0x00000051 | 73 | #define FSF_GENERIC_COMMAND_REJECTED 0x00000051 |
74 | #define FSF_OPERATION_PARTIALLY_SUCCESSFUL 0x00000052 | ||
75 | #define FSF_AUTHORIZATION_FAILURE 0x00000053 | ||
76 | #define FSF_CFDC_ERROR_DETECTED 0x00000054 | ||
77 | #define FSF_CONTROL_FILE_UPDATE_ERROR 0x00000055 | ||
78 | #define FSF_CONTROL_FILE_TOO_LARGE 0x00000056 | ||
79 | #define FSF_ACCESS_CONFLICT_DETECTED 0x00000057 | ||
80 | #define FSF_CONFLICTS_OVERRULED 0x00000058 | ||
81 | #define FSF_PORT_BOXED 0x00000059 | 74 | #define FSF_PORT_BOXED 0x00000059 |
82 | #define FSF_LUN_BOXED 0x0000005A | 75 | #define FSF_LUN_BOXED 0x0000005A |
83 | #define FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE 0x0000005B | 76 | #define FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE 0x0000005B |
@@ -85,9 +78,7 @@ | |||
85 | #define FSF_REQUEST_SIZE_TOO_LARGE 0x00000061 | 78 | #define FSF_REQUEST_SIZE_TOO_LARGE 0x00000061 |
86 | #define FSF_RESPONSE_SIZE_TOO_LARGE 0x00000062 | 79 | #define FSF_RESPONSE_SIZE_TOO_LARGE 0x00000062 |
87 | #define FSF_SBAL_MISMATCH 0x00000063 | 80 | #define FSF_SBAL_MISMATCH 0x00000063 |
88 | #define FSF_OPEN_PORT_WITHOUT_PRLI 0x00000064 | ||
89 | #define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD | 81 | #define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD |
90 | #define FSF_FCP_RSP_AVAILABLE 0x000000AF | ||
91 | #define FSF_UNKNOWN_COMMAND 0x000000E2 | 82 | #define FSF_UNKNOWN_COMMAND 0x000000E2 |
92 | #define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3 | 83 | #define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3 |
93 | #define FSF_INVALID_COMMAND_OPTION 0x000000E5 | 84 | #define FSF_INVALID_COMMAND_OPTION 0x000000E5 |
@@ -102,20 +93,9 @@ | |||
102 | #define FSF_SQ_RETRY_IF_POSSIBLE 0x02 | 93 | #define FSF_SQ_RETRY_IF_POSSIBLE 0x02 |
103 | #define FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED 0x03 | 94 | #define FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED 0x03 |
104 | #define FSF_SQ_INVOKE_LINK_TEST_PROCEDURE 0x04 | 95 | #define FSF_SQ_INVOKE_LINK_TEST_PROCEDURE 0x04 |
105 | #define FSF_SQ_ULP_PROGRAMMING_ERROR 0x05 | ||
106 | #define FSF_SQ_COMMAND_ABORTED 0x06 | 96 | #define FSF_SQ_COMMAND_ABORTED 0x06 |
107 | #define FSF_SQ_NO_RETRY_POSSIBLE 0x07 | 97 | #define FSF_SQ_NO_RETRY_POSSIBLE 0x07 |
108 | 98 | ||
109 | /* FSF status qualifier for CFDC commands */ | ||
110 | #define FSF_SQ_CFDC_HARDENED_ON_SE 0x00000000 | ||
111 | #define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE 0x00000001 | ||
112 | #define FSF_SQ_CFDC_COULD_NOT_HARDEN_ON_SE2 0x00000002 | ||
113 | /* CFDC subtable codes */ | ||
114 | #define FSF_SQ_CFDC_SUBTABLE_OS 0x0001 | ||
115 | #define FSF_SQ_CFDC_SUBTABLE_PORT_WWPN 0x0002 | ||
116 | #define FSF_SQ_CFDC_SUBTABLE_PORT_DID 0x0003 | ||
117 | #define FSF_SQ_CFDC_SUBTABLE_LUN 0x0004 | ||
118 | |||
119 | /* FSF status qualifier (most significant 4 bytes), local link down */ | 99 | /* FSF status qualifier (most significant 4 bytes), local link down */ |
120 | #define FSF_PSQ_LINK_NO_LIGHT 0x00000004 | 100 | #define FSF_PSQ_LINK_NO_LIGHT 0x00000004 |
121 | #define FSF_PSQ_LINK_WRAP_PLUG 0x00000008 | 101 | #define FSF_PSQ_LINK_WRAP_PLUG 0x00000008 |
@@ -145,7 +125,6 @@ | |||
145 | #define FSF_STATUS_READ_LINK_UP 0x00000006 | 125 | #define FSF_STATUS_READ_LINK_UP 0x00000006 |
146 | #define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009 | 126 | #define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009 |
147 | #define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A | 127 | #define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A |
148 | #define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B | ||
149 | #define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C | 128 | #define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C |
150 | 129 | ||
151 | /* status subtypes in status read buffer */ | 130 | /* status subtypes in status read buffer */ |
@@ -159,20 +138,9 @@ | |||
159 | 138 | ||
160 | /* status subtypes for unsolicited status notification lost */ | 139 | /* status subtypes for unsolicited status notification lost */ |
161 | #define FSF_STATUS_READ_SUB_INCOMING_ELS 0x00000001 | 140 | #define FSF_STATUS_READ_SUB_INCOMING_ELS 0x00000001 |
162 | #define FSF_STATUS_READ_SUB_SENSE_DATA 0x00000002 | ||
163 | #define FSF_STATUS_READ_SUB_LINK_STATUS 0x00000004 | ||
164 | #define FSF_STATUS_READ_SUB_PORT_CLOSED 0x00000008 | ||
165 | #define FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD 0x00000010 | ||
166 | #define FSF_STATUS_READ_SUB_ACT_UPDATED 0x00000020 | 141 | #define FSF_STATUS_READ_SUB_ACT_UPDATED 0x00000020 |
167 | #define FSF_STATUS_READ_SUB_ACT_HARDENED 0x00000040 | ||
168 | #define FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT 0x00000080 | ||
169 | |||
170 | /* status subtypes for CFDC */ | ||
171 | #define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002 | ||
172 | #define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F | ||
173 | 142 | ||
174 | /* topologie that is detected by the adapter */ | 143 | /* topologie that is detected by the adapter */ |
175 | #define FSF_TOPO_ERROR 0x00000000 | ||
176 | #define FSF_TOPO_P2P 0x00000001 | 144 | #define FSF_TOPO_P2P 0x00000001 |
177 | #define FSF_TOPO_FABRIC 0x00000002 | 145 | #define FSF_TOPO_FABRIC 0x00000002 |
178 | #define FSF_TOPO_AL 0x00000003 | 146 | #define FSF_TOPO_AL 0x00000003 |
@@ -180,17 +148,13 @@ | |||
180 | /* data direction for FCP commands */ | 148 | /* data direction for FCP commands */ |
181 | #define FSF_DATADIR_WRITE 0x00000001 | 149 | #define FSF_DATADIR_WRITE 0x00000001 |
182 | #define FSF_DATADIR_READ 0x00000002 | 150 | #define FSF_DATADIR_READ 0x00000002 |
183 | #define FSF_DATADIR_READ_WRITE 0x00000003 | ||
184 | #define FSF_DATADIR_CMND 0x00000004 | 151 | #define FSF_DATADIR_CMND 0x00000004 |
185 | 152 | ||
186 | /* fc service class */ | 153 | /* fc service class */ |
187 | #define FSF_CLASS_1 0x00000001 | ||
188 | #define FSF_CLASS_2 0x00000002 | ||
189 | #define FSF_CLASS_3 0x00000003 | 154 | #define FSF_CLASS_3 0x00000003 |
190 | 155 | ||
191 | /* SBAL chaining */ | 156 | /* SBAL chaining */ |
192 | #define FSF_MAX_SBALS_PER_REQ 36 | 157 | #define FSF_MAX_SBALS_PER_REQ 36 |
193 | #define FSF_MAX_SBALS_PER_ELS_REQ 2 | ||
194 | 158 | ||
195 | /* logging space behind QTCB */ | 159 | /* logging space behind QTCB */ |
196 | #define FSF_QTCB_LOG_SIZE 1024 | 160 | #define FSF_QTCB_LOG_SIZE 1024 |
@@ -200,50 +164,16 @@ | |||
200 | #define FSF_FEATURE_LUN_SHARING 0x00000004 | 164 | #define FSF_FEATURE_LUN_SHARING 0x00000004 |
201 | #define FSF_FEATURE_NOTIFICATION_LOST 0x00000008 | 165 | #define FSF_FEATURE_NOTIFICATION_LOST 0x00000008 |
202 | #define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010 | 166 | #define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010 |
203 | #define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020 | ||
204 | #define FSF_FEATURE_UPDATE_ALERT 0x00000100 | 167 | #define FSF_FEATURE_UPDATE_ALERT 0x00000100 |
205 | #define FSF_FEATURE_MEASUREMENT_DATA 0x00000200 | 168 | #define FSF_FEATURE_MEASUREMENT_DATA 0x00000200 |
206 | 169 | ||
207 | /* host connection features */ | 170 | /* host connection features */ |
208 | #define FSF_FEATURE_NPIV_MODE 0x00000001 | 171 | #define FSF_FEATURE_NPIV_MODE 0x00000001 |
209 | #define FSF_FEATURE_VM_ASSIGNED_WWPN 0x00000002 | ||
210 | 172 | ||
211 | /* option */ | 173 | /* option */ |
212 | #define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001 | 174 | #define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001 |
213 | #define FSF_OPEN_LUN_REPLICATE_SENSE 0x00000002 | ||
214 | |||
215 | /* adapter types */ | ||
216 | #define FSF_ADAPTER_TYPE_FICON 0x00000001 | ||
217 | #define FSF_ADAPTER_TYPE_FICON_EXPRESS 0x00000002 | ||
218 | |||
219 | /* port types */ | ||
220 | #define FSF_HBA_PORTTYPE_UNKNOWN 0x00000001 | ||
221 | #define FSF_HBA_PORTTYPE_NOTPRESENT 0x00000003 | ||
222 | #define FSF_HBA_PORTTYPE_NPORT 0x00000005 | ||
223 | #define FSF_HBA_PORTTYPE_PTP 0x00000021 | ||
224 | /* following are not defined and used by FSF Spec | ||
225 | but are additionally defined by FC-HBA */ | ||
226 | #define FSF_HBA_PORTTYPE_OTHER 0x00000002 | ||
227 | #define FSF_HBA_PORTTYPE_NOTPRESENT 0x00000003 | ||
228 | #define FSF_HBA_PORTTYPE_NLPORT 0x00000006 | ||
229 | #define FSF_HBA_PORTTYPE_FLPORT 0x00000007 | ||
230 | #define FSF_HBA_PORTTYPE_FPORT 0x00000008 | ||
231 | #define FSF_HBA_PORTTYPE_LPORT 0x00000020 | ||
232 | |||
233 | /* port states */ | ||
234 | #define FSF_HBA_PORTSTATE_UNKNOWN 0x00000001 | ||
235 | #define FSF_HBA_PORTSTATE_ONLINE 0x00000002 | ||
236 | #define FSF_HBA_PORTSTATE_OFFLINE 0x00000003 | ||
237 | #define FSF_HBA_PORTSTATE_LINKDOWN 0x00000006 | ||
238 | #define FSF_HBA_PORTSTATE_ERROR 0x00000007 | ||
239 | |||
240 | /* IO states of adapter */ | ||
241 | #define FSF_IOSTAT_NPORT_RJT 0x00000004 | ||
242 | #define FSF_IOSTAT_FABRIC_RJT 0x00000005 | ||
243 | #define FSF_IOSTAT_LS_RJT 0x00000009 | ||
244 | 175 | ||
245 | /* open LUN access flags*/ | 176 | /* open LUN access flags*/ |
246 | #define FSF_UNIT_ACCESS_OPEN_LUN_ALLOWED 0x01000000 | ||
247 | #define FSF_UNIT_ACCESS_EXCLUSIVE 0x02000000 | 177 | #define FSF_UNIT_ACCESS_EXCLUSIVE 0x02000000 |
248 | #define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER 0x10000000 | 178 | #define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER 0x10000000 |
249 | 179 | ||
@@ -265,11 +195,6 @@ struct fsf_queue_designator { | |||
265 | u32 res1; | 195 | u32 res1; |
266 | } __attribute__ ((packed)); | 196 | } __attribute__ ((packed)); |
267 | 197 | ||
268 | struct fsf_port_closed_payload { | ||
269 | struct fsf_queue_designator queue_designator; | ||
270 | u32 port_handle; | ||
271 | } __attribute__ ((packed)); | ||
272 | |||
273 | struct fsf_bit_error_payload { | 198 | struct fsf_bit_error_payload { |
274 | u32 res1; | 199 | u32 res1; |
275 | u32 link_failure_error_count; | 200 | u32 link_failure_error_count; |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 69d632d851d9..3e05080e62d4 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -28,7 +28,7 @@ static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal) | |||
28 | return 0; | 28 | return 0; |
29 | } | 29 | } |
30 | 30 | ||
31 | static volatile struct qdio_buffer_element * | 31 | static struct qdio_buffer_element * |
32 | zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx) | 32 | zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx) |
33 | { | 33 | { |
34 | return &q->sbal[sbal_idx]->element[sbale_idx]; | 34 | return &q->sbal[sbal_idx]->element[sbale_idx]; |
@@ -57,7 +57,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter) | |||
57 | 57 | ||
58 | static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id) | 58 | static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id) |
59 | { | 59 | { |
60 | dev_warn(&adapter->ccw_device->dev, "QDIO problem occurred.\n"); | 60 | dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n"); |
61 | 61 | ||
62 | zfcp_erp_adapter_reopen(adapter, | 62 | zfcp_erp_adapter_reopen(adapter, |
63 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | | 63 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | |
@@ -145,7 +145,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
145 | { | 145 | { |
146 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; | 146 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm; |
147 | struct zfcp_qdio_queue *queue = &adapter->resp_q; | 147 | struct zfcp_qdio_queue *queue = &adapter->resp_q; |
148 | volatile struct qdio_buffer_element *sbale; | 148 | struct qdio_buffer_element *sbale; |
149 | int sbal_idx, sbale_idx, sbal_no; | 149 | int sbal_idx, sbale_idx, sbal_no; |
150 | 150 | ||
151 | if (unlikely(qdio_err)) { | 151 | if (unlikely(qdio_err)) { |
@@ -174,8 +174,8 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
174 | 174 | ||
175 | if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY))) | 175 | if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY))) |
176 | dev_warn(&adapter->ccw_device->dev, | 176 | dev_warn(&adapter->ccw_device->dev, |
177 | "Protocol violation by adapter. " | 177 | "A QDIO protocol error occurred, " |
178 | "Continuing operations.\n"); | 178 | "operations continue\n"); |
179 | } | 179 | } |
180 | 180 | ||
181 | /* | 181 | /* |
@@ -190,8 +190,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
190 | * @fsf_req: pointer to struct fsf_req | 190 | * @fsf_req: pointer to struct fsf_req |
191 | * Returns: pointer to qdio_buffer_element (SBALE) structure | 191 | * Returns: pointer to qdio_buffer_element (SBALE) structure |
192 | */ | 192 | */ |
193 | volatile struct qdio_buffer_element * | 193 | struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) |
194 | zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) | ||
195 | { | 194 | { |
196 | return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0); | 195 | return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0); |
197 | } | 196 | } |
@@ -201,8 +200,7 @@ zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) | |||
201 | * @fsf_req: pointer to struct fsf_req | 200 | * @fsf_req: pointer to struct fsf_req |
202 | * Returns: pointer to qdio_buffer_element (SBALE) structure | 201 | * Returns: pointer to qdio_buffer_element (SBALE) structure |
203 | */ | 202 | */ |
204 | volatile struct qdio_buffer_element * | 203 | struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req) |
205 | zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req) | ||
206 | { | 204 | { |
207 | return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, | 205 | return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, |
208 | req->sbale_curr); | 206 | req->sbale_curr); |
@@ -216,10 +214,10 @@ static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals) | |||
216 | % QDIO_MAX_BUFFERS_PER_Q; | 214 | % QDIO_MAX_BUFFERS_PER_Q; |
217 | } | 215 | } |
218 | 216 | ||
219 | static volatile struct qdio_buffer_element * | 217 | static struct qdio_buffer_element * |
220 | zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) | 218 | zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) |
221 | { | 219 | { |
222 | volatile struct qdio_buffer_element *sbale; | 220 | struct qdio_buffer_element *sbale; |
223 | 221 | ||
224 | /* set last entry flag in current SBALE of current SBAL */ | 222 | /* set last entry flag in current SBALE of current SBAL */ |
225 | sbale = zfcp_qdio_sbale_curr(fsf_req); | 223 | sbale = zfcp_qdio_sbale_curr(fsf_req); |
@@ -250,7 +248,7 @@ zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) | |||
250 | return sbale; | 248 | return sbale; |
251 | } | 249 | } |
252 | 250 | ||
253 | static volatile struct qdio_buffer_element * | 251 | static struct qdio_buffer_element * |
254 | zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) | 252 | zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) |
255 | { | 253 | { |
256 | if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) | 254 | if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) |
@@ -273,7 +271,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, | |||
273 | unsigned int sbtype, void *start_addr, | 271 | unsigned int sbtype, void *start_addr, |
274 | unsigned int total_length) | 272 | unsigned int total_length) |
275 | { | 273 | { |
276 | volatile struct qdio_buffer_element *sbale; | 274 | struct qdio_buffer_element *sbale; |
277 | unsigned long remaining, length; | 275 | unsigned long remaining, length; |
278 | void *addr; | 276 | void *addr; |
279 | 277 | ||
@@ -282,6 +280,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, | |||
282 | addr += length, remaining -= length) { | 280 | addr += length, remaining -= length) { |
283 | sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); | 281 | sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); |
284 | if (!sbale) { | 282 | if (!sbale) { |
283 | atomic_inc(&fsf_req->adapter->qdio_outb_full); | ||
285 | zfcp_qdio_undo_sbals(fsf_req); | 284 | zfcp_qdio_undo_sbals(fsf_req); |
286 | return -EINVAL; | 285 | return -EINVAL; |
287 | } | 286 | } |
@@ -307,7 +306,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, | |||
307 | int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, | 306 | int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, |
308 | struct scatterlist *sg, int max_sbals) | 307 | struct scatterlist *sg, int max_sbals) |
309 | { | 308 | { |
310 | volatile struct qdio_buffer_element *sbale; | 309 | struct qdio_buffer_element *sbale; |
311 | int retval, bytes = 0; | 310 | int retval, bytes = 0; |
312 | 311 | ||
313 | /* figure out last allowed SBAL */ | 312 | /* figure out last allowed SBAL */ |
@@ -344,10 +343,10 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) | |||
344 | int first = fsf_req->sbal_first; | 343 | int first = fsf_req->sbal_first; |
345 | int count = fsf_req->sbal_number; | 344 | int count = fsf_req->sbal_number; |
346 | int retval, pci, pci_batch; | 345 | int retval, pci, pci_batch; |
347 | volatile struct qdio_buffer_element *sbale; | 346 | struct qdio_buffer_element *sbale; |
348 | 347 | ||
349 | /* acknowledgements for transferred buffers */ | 348 | /* acknowledgements for transferred buffers */ |
350 | pci_batch = req_q->pci_batch + count; | 349 | pci_batch = adapter->req_q_pci_batch + count; |
351 | if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) { | 350 | if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) { |
352 | pci_batch %= ZFCP_QDIO_PCI_INTERVAL; | 351 | pci_batch %= ZFCP_QDIO_PCI_INTERVAL; |
353 | pci = first + count - (pci_batch + 1); | 352 | pci = first + count - (pci_batch + 1); |
@@ -367,7 +366,7 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) | |||
367 | atomic_sub(count, &req_q->count); | 366 | atomic_sub(count, &req_q->count); |
368 | req_q->first += count; | 367 | req_q->first += count; |
369 | req_q->first %= QDIO_MAX_BUFFERS_PER_Q; | 368 | req_q->first %= QDIO_MAX_BUFFERS_PER_Q; |
370 | req_q->pci_batch = pci_batch; | 369 | adapter->req_q_pci_batch = pci_batch; |
371 | return 0; | 370 | return 0; |
372 | } | 371 | } |
373 | 372 | ||
@@ -418,14 +417,14 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) | |||
418 | struct zfcp_qdio_queue *req_q; | 417 | struct zfcp_qdio_queue *req_q; |
419 | int first, count; | 418 | int first, count; |
420 | 419 | ||
421 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) | 420 | if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) |
422 | return; | 421 | return; |
423 | 422 | ||
424 | /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ | 423 | /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ |
425 | req_q = &adapter->req_q; | 424 | req_q = &adapter->req_q; |
426 | spin_lock_bh(&req_q->lock); | 425 | spin_lock_bh(&adapter->req_q_lock); |
427 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); | 426 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); |
428 | spin_unlock_bh(&req_q->lock); | 427 | spin_unlock_bh(&adapter->req_q_lock); |
429 | 428 | ||
430 | qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); | 429 | qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); |
431 | 430 | ||
@@ -438,7 +437,7 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) | |||
438 | } | 437 | } |
439 | req_q->first = 0; | 438 | req_q->first = 0; |
440 | atomic_set(&req_q->count, 0); | 439 | atomic_set(&req_q->count, 0); |
441 | req_q->pci_batch = 0; | 440 | adapter->req_q_pci_batch = 0; |
442 | adapter->resp_q.first = 0; | 441 | adapter->resp_q.first = 0; |
443 | atomic_set(&adapter->resp_q.count, 0); | 442 | atomic_set(&adapter->resp_q.count, 0); |
444 | } | 443 | } |
@@ -450,23 +449,17 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) | |||
450 | */ | 449 | */ |
451 | int zfcp_qdio_open(struct zfcp_adapter *adapter) | 450 | int zfcp_qdio_open(struct zfcp_adapter *adapter) |
452 | { | 451 | { |
453 | volatile struct qdio_buffer_element *sbale; | 452 | struct qdio_buffer_element *sbale; |
454 | int cc; | 453 | int cc; |
455 | 454 | ||
456 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) | 455 | if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP) |
457 | return -EIO; | 456 | return -EIO; |
458 | 457 | ||
459 | if (qdio_establish(&adapter->qdio_init_data)) { | 458 | if (qdio_establish(&adapter->qdio_init_data)) |
460 | dev_err(&adapter->ccw_device->dev, | 459 | goto failed_establish; |
461 | "Establish of QDIO queues failed.\n"); | ||
462 | return -EIO; | ||
463 | } | ||
464 | 460 | ||
465 | if (qdio_activate(adapter->ccw_device)) { | 461 | if (qdio_activate(adapter->ccw_device)) |
466 | dev_err(&adapter->ccw_device->dev, | ||
467 | "Activate of QDIO queues failed.\n"); | ||
468 | goto failed_qdio; | 462 | goto failed_qdio; |
469 | } | ||
470 | 463 | ||
471 | for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { | 464 | for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) { |
472 | sbale = &(adapter->resp_q.sbal[cc]->element[0]); | 465 | sbale = &(adapter->resp_q.sbal[cc]->element[0]); |
@@ -476,20 +469,20 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter) | |||
476 | } | 469 | } |
477 | 470 | ||
478 | if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0, | 471 | if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0, |
479 | QDIO_MAX_BUFFERS_PER_Q)) { | 472 | QDIO_MAX_BUFFERS_PER_Q)) |
480 | dev_err(&adapter->ccw_device->dev, | ||
481 | "Init of QDIO response queue failed.\n"); | ||
482 | goto failed_qdio; | 473 | goto failed_qdio; |
483 | } | ||
484 | 474 | ||
485 | /* set index of first avalable SBALS / number of available SBALS */ | 475 | /* set index of first avalable SBALS / number of available SBALS */ |
486 | adapter->req_q.first = 0; | 476 | adapter->req_q.first = 0; |
487 | atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q); | 477 | atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q); |
488 | adapter->req_q.pci_batch = 0; | 478 | adapter->req_q_pci_batch = 0; |
489 | 479 | ||
490 | return 0; | 480 | return 0; |
491 | 481 | ||
492 | failed_qdio: | 482 | failed_qdio: |
493 | qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); | 483 | qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); |
484 | failed_establish: | ||
485 | dev_err(&adapter->ccw_device->dev, | ||
486 | "Setting up the QDIO connection to the FCP adapter failed\n"); | ||
494 | return -EIO; | 487 | return -EIO; |
495 | } | 488 | } |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index aeae56b00b45..ca8f85f3dad4 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -21,20 +21,6 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu) | |||
21 | return fcp_sns_info_ptr; | 21 | return fcp_sns_info_ptr; |
22 | } | 22 | } |
23 | 23 | ||
24 | void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, fcp_dl_t fcp_dl) | ||
25 | { | ||
26 | fcp_dl_t *fcp_dl_ptr; | ||
27 | |||
28 | /* | ||
29 | * fcp_dl_addr = start address of fcp_cmnd structure + | ||
30 | * size of fixed part + size of dynamically sized add_dcp_cdb field | ||
31 | * SEE FCP-2 documentation | ||
32 | */ | ||
33 | fcp_dl_ptr = (fcp_dl_t *) ((unsigned char *) &fcp_cmd[1] + | ||
34 | (fcp_cmd->add_fcp_cdb_length << 2)); | ||
35 | *fcp_dl_ptr = fcp_dl; | ||
36 | } | ||
37 | |||
38 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | 24 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) |
39 | { | 25 | { |
40 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 26 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; |
@@ -119,13 +105,17 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *adapter, | |||
119 | { | 105 | { |
120 | struct zfcp_port *port; | 106 | struct zfcp_port *port; |
121 | struct zfcp_unit *unit; | 107 | struct zfcp_unit *unit; |
108 | int scsi_lun; | ||
122 | 109 | ||
123 | list_for_each_entry(port, &adapter->port_list_head, list) { | 110 | list_for_each_entry(port, &adapter->port_list_head, list) { |
124 | if (!port->rport || (id != port->rport->scsi_target_id)) | 111 | if (!port->rport || (id != port->rport->scsi_target_id)) |
125 | continue; | 112 | continue; |
126 | list_for_each_entry(unit, &port->unit_list_head, list) | 113 | list_for_each_entry(unit, &port->unit_list_head, list) { |
127 | if (lun == unit->scsi_lun) | 114 | scsi_lun = scsilun_to_int( |
115 | (struct scsi_lun *)&unit->fcp_lun); | ||
116 | if (lun == scsi_lun) | ||
128 | return unit; | 117 | return unit; |
118 | } | ||
129 | } | 119 | } |
130 | 120 | ||
131 | return NULL; | 121 | return NULL; |
@@ -183,7 +173,6 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
183 | return retval; | 173 | return retval; |
184 | } | 174 | } |
185 | fsf_req->data = NULL; | 175 | fsf_req->data = NULL; |
186 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING; | ||
187 | 176 | ||
188 | /* don't access old fsf_req after releasing the abort_lock */ | 177 | /* don't access old fsf_req after releasing the abort_lock */ |
189 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 178 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
@@ -294,7 +283,8 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | |||
294 | sizeof (struct zfcp_adapter *)); | 283 | sizeof (struct zfcp_adapter *)); |
295 | if (!adapter->scsi_host) { | 284 | if (!adapter->scsi_host) { |
296 | dev_err(&adapter->ccw_device->dev, | 285 | dev_err(&adapter->ccw_device->dev, |
297 | "registration with SCSI stack failed."); | 286 | "Registering the FCP device with the " |
287 | "SCSI stack failed\n"); | ||
298 | return -EIO; | 288 | return -EIO; |
299 | } | 289 | } |
300 | 290 | ||
@@ -312,7 +302,6 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter) | |||
312 | scsi_host_put(adapter->scsi_host); | 302 | scsi_host_put(adapter->scsi_host); |
313 | return -EIO; | 303 | return -EIO; |
314 | } | 304 | } |
315 | atomic_set_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status); | ||
316 | 305 | ||
317 | return 0; | 306 | return 0; |
318 | } | 307 | } |
@@ -336,7 +325,6 @@ void zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) | |||
336 | scsi_remove_host(shost); | 325 | scsi_remove_host(shost); |
337 | scsi_host_put(shost); | 326 | scsi_host_put(shost); |
338 | adapter->scsi_host = NULL; | 327 | adapter->scsi_host = NULL; |
339 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status); | ||
340 | 328 | ||
341 | return; | 329 | return; |
342 | } | 330 | } |
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 2e85c6c49e7d..2809d789b55c 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c | |||
@@ -26,9 +26,9 @@ static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO, \ | |||
26 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, status, "0x%08x\n", | 26 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, status, "0x%08x\n", |
27 | atomic_read(&adapter->status)); | 27 | atomic_read(&adapter->status)); |
28 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwnn, "0x%016llx\n", | 28 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwnn, "0x%016llx\n", |
29 | adapter->peer_wwnn); | 29 | (unsigned long long) adapter->peer_wwnn); |
30 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwpn, "0x%016llx\n", | 30 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_wwpn, "0x%016llx\n", |
31 | adapter->peer_wwpn); | 31 | (unsigned long long) adapter->peer_wwpn); |
32 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_d_id, "0x%06x\n", | 32 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, peer_d_id, "0x%06x\n", |
33 | adapter->peer_d_id); | 33 | adapter->peer_d_id); |
34 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, card_version, "0x%04x\n", | 34 | ZFCP_DEFINE_ATTR(zfcp_adapter, adapter, card_version, "0x%04x\n", |
@@ -135,8 +135,9 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, | |||
135 | { | 135 | { |
136 | struct zfcp_adapter *adapter = dev_get_drvdata(dev); | 136 | struct zfcp_adapter *adapter = dev_get_drvdata(dev); |
137 | struct zfcp_port *port; | 137 | struct zfcp_port *port; |
138 | wwn_t wwpn; | 138 | u64 wwpn; |
139 | int retval = 0; | 139 | int retval = 0; |
140 | LIST_HEAD(port_remove_lh); | ||
140 | 141 | ||
141 | down(&zfcp_data.config_sema); | 142 | down(&zfcp_data.config_sema); |
142 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { | 143 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) { |
@@ -144,7 +145,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, | |||
144 | goto out; | 145 | goto out; |
145 | } | 146 | } |
146 | 147 | ||
147 | if (strict_strtoull(buf, 0, &wwpn)) { | 148 | if (strict_strtoull(buf, 0, (unsigned long long *) &wwpn)) { |
148 | retval = -EINVAL; | 149 | retval = -EINVAL; |
149 | goto out; | 150 | goto out; |
150 | } | 151 | } |
@@ -154,7 +155,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, | |||
154 | if (port && (atomic_read(&port->refcount) == 0)) { | 155 | if (port && (atomic_read(&port->refcount) == 0)) { |
155 | zfcp_port_get(port); | 156 | zfcp_port_get(port); |
156 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | 157 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); |
157 | list_move(&port->list, &adapter->port_remove_lh); | 158 | list_move(&port->list, &port_remove_lh); |
158 | } else | 159 | } else |
159 | port = NULL; | 160 | port = NULL; |
160 | write_unlock_irq(&zfcp_data.config_lock); | 161 | write_unlock_irq(&zfcp_data.config_lock); |
@@ -200,7 +201,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, | |||
200 | { | 201 | { |
201 | struct zfcp_port *port = dev_get_drvdata(dev); | 202 | struct zfcp_port *port = dev_get_drvdata(dev); |
202 | struct zfcp_unit *unit; | 203 | struct zfcp_unit *unit; |
203 | fcp_lun_t fcp_lun; | 204 | u64 fcp_lun; |
204 | int retval = -EINVAL; | 205 | int retval = -EINVAL; |
205 | 206 | ||
206 | down(&zfcp_data.config_sema); | 207 | down(&zfcp_data.config_sema); |
@@ -209,7 +210,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev, | |||
209 | goto out; | 210 | goto out; |
210 | } | 211 | } |
211 | 212 | ||
212 | if (strict_strtoull(buf, 0, &fcp_lun)) | 213 | if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) |
213 | goto out; | 214 | goto out; |
214 | 215 | ||
215 | unit = zfcp_unit_enqueue(port, fcp_lun); | 216 | unit = zfcp_unit_enqueue(port, fcp_lun); |
@@ -233,8 +234,9 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, | |||
233 | { | 234 | { |
234 | struct zfcp_port *port = dev_get_drvdata(dev); | 235 | struct zfcp_port *port = dev_get_drvdata(dev); |
235 | struct zfcp_unit *unit; | 236 | struct zfcp_unit *unit; |
236 | fcp_lun_t fcp_lun; | 237 | u64 fcp_lun; |
237 | int retval = 0; | 238 | int retval = 0; |
239 | LIST_HEAD(unit_remove_lh); | ||
238 | 240 | ||
239 | down(&zfcp_data.config_sema); | 241 | down(&zfcp_data.config_sema); |
240 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { | 242 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) { |
@@ -242,7 +244,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, | |||
242 | goto out; | 244 | goto out; |
243 | } | 245 | } |
244 | 246 | ||
245 | if (strict_strtoull(buf, 0, &fcp_lun)) { | 247 | if (strict_strtoull(buf, 0, (unsigned long long *) &fcp_lun)) { |
246 | retval = -EINVAL; | 248 | retval = -EINVAL; |
247 | goto out; | 249 | goto out; |
248 | } | 250 | } |
@@ -252,7 +254,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev, | |||
252 | if (unit && (atomic_read(&unit->refcount) == 0)) { | 254 | if (unit && (atomic_read(&unit->refcount) == 0)) { |
253 | zfcp_unit_get(unit); | 255 | zfcp_unit_get(unit); |
254 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); | 256 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); |
255 | list_move(&unit->list, &port->unit_remove_lh); | 257 | list_move(&unit->list, &unit_remove_lh); |
256 | } else | 258 | } else |
257 | unit = NULL; | 259 | unit = NULL; |
258 | 260 | ||
@@ -273,22 +275,7 @@ out: | |||
273 | } | 275 | } |
274 | static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); | 276 | static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); |
275 | 277 | ||
276 | static struct attribute *zfcp_port_ns_attrs[] = { | 278 | static struct attribute *zfcp_port_attrs[] = { |
277 | &dev_attr_port_failed.attr, | ||
278 | &dev_attr_port_in_recovery.attr, | ||
279 | &dev_attr_port_status.attr, | ||
280 | &dev_attr_port_access_denied.attr, | ||
281 | NULL | ||
282 | }; | ||
283 | |||
284 | /** | ||
285 | * zfcp_sysfs_ns_port_attrs - sysfs attributes for nameserver | ||
286 | */ | ||
287 | struct attribute_group zfcp_sysfs_ns_port_attrs = { | ||
288 | .attrs = zfcp_port_ns_attrs, | ||
289 | }; | ||
290 | |||
291 | static struct attribute *zfcp_port_no_ns_attrs[] = { | ||
292 | &dev_attr_unit_add.attr, | 279 | &dev_attr_unit_add.attr, |
293 | &dev_attr_unit_remove.attr, | 280 | &dev_attr_unit_remove.attr, |
294 | &dev_attr_port_failed.attr, | 281 | &dev_attr_port_failed.attr, |
@@ -302,7 +289,7 @@ static struct attribute *zfcp_port_no_ns_attrs[] = { | |||
302 | * zfcp_sysfs_port_attrs - sysfs attributes for all other ports | 289 | * zfcp_sysfs_port_attrs - sysfs attributes for all other ports |
303 | */ | 290 | */ |
304 | struct attribute_group zfcp_sysfs_port_attrs = { | 291 | struct attribute_group zfcp_sysfs_port_attrs = { |
305 | .attrs = zfcp_port_no_ns_attrs, | 292 | .attrs = zfcp_port_attrs, |
306 | }; | 293 | }; |
307 | 294 | ||
308 | static struct attribute *zfcp_unit_attrs[] = { | 295 | static struct attribute *zfcp_unit_attrs[] = { |
@@ -395,8 +382,10 @@ static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL); | |||
395 | 382 | ||
396 | ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", | 383 | ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n", |
397 | unit->port->adapter->ccw_device->dev.bus_id); | 384 | unit->port->adapter->ccw_device->dev.bus_id); |
398 | ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", unit->port->wwpn); | 385 | ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n", |
399 | ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", unit->fcp_lun); | 386 | (unsigned long long) unit->port->wwpn); |
387 | ZFCP_DEFINE_SCSI_ATTR(fcp_lun, "0x%016llx\n", | ||
388 | (unsigned long long) unit->fcp_lun); | ||
400 | 389 | ||
401 | struct device_attribute *zfcp_sysfs_sdev_attrs[] = { | 390 | struct device_attribute *zfcp_sysfs_sdev_attrs[] = { |
402 | &dev_attr_fcp_lun, | 391 | &dev_attr_fcp_lun, |
@@ -487,10 +476,23 @@ ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n", | |||
487 | ZFCP_SHOST_ATTR(seconds_active, "%llu\n", | 476 | ZFCP_SHOST_ATTR(seconds_active, "%llu\n", |
488 | (unsigned long long) stat_info.seconds_act); | 477 | (unsigned long long) stat_info.seconds_act); |
489 | 478 | ||
479 | static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev, | ||
480 | struct device_attribute *attr, | ||
481 | char *buf) | ||
482 | { | ||
483 | struct Scsi_Host *scsi_host = class_to_shost(dev); | ||
484 | struct zfcp_adapter *adapter = | ||
485 | (struct zfcp_adapter *) scsi_host->hostdata[0]; | ||
486 | |||
487 | return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full)); | ||
488 | } | ||
489 | static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); | ||
490 | |||
490 | struct device_attribute *zfcp_sysfs_shost_attrs[] = { | 491 | struct device_attribute *zfcp_sysfs_shost_attrs[] = { |
491 | &dev_attr_utilization, | 492 | &dev_attr_utilization, |
492 | &dev_attr_requests, | 493 | &dev_attr_requests, |
493 | &dev_attr_megabytes, | 494 | &dev_attr_megabytes, |
494 | &dev_attr_seconds_active, | 495 | &dev_attr_seconds_active, |
496 | &dev_attr_queue_full, | ||
495 | NULL | 497 | NULL |
496 | }; | 498 | }; |