summaryrefslogtreecommitdiff
path: root/drivers/s390/scsi/zfcp_aux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 8c7e2b778ef1..1383f42f21ff 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -839,7 +839,7 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
unit->fcp_lun = fcp_lun;
/* setup for sysfs registration */
- snprintf(unit->sysfs_device.bus_id, BUS_ID_SIZE, "0x%016llx", fcp_lun);
+ dev_set_name(&unit->sysfs_device, "0x%016llx", fcp_lun);
unit->sysfs_device.parent = &port->sysfs_device;
unit->sysfs_device.release = zfcp_sysfs_unit_release;
dev_set_drvdata(&unit->sysfs_device, unit);
@@ -847,6 +847,14 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
/* mark unit unusable as long as sysfs registration is not complete */
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
+ spin_lock_init(&unit->latencies.lock);
+ unit->latencies.write.channel.min = 0xFFFFFFFF;
+ unit->latencies.write.fabric.min = 0xFFFFFFFF;
+ unit->latencies.read.channel.min = 0xFFFFFFFF;
+ unit->latencies.read.fabric.min = 0xFFFFFFFF;
+ unit->latencies.cmd.channel.min = 0xFFFFFFFF;
+ unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
+
if (device_register(&unit->sysfs_device)) {
kfree(unit);
return NULL;
@@ -962,6 +970,27 @@ static void zfcp_dummy_release(struct device *dev)
return;
}
+int zfcp_status_read_refill(struct zfcp_adapter *adapter)
+{
+ while (atomic_read(&adapter->stat_miss) > 0)
+ if (zfcp_fsf_status_read(adapter, ZFCP_WAIT_FOR_SBAL))
+ break;
+ else
+ atomic_dec(&adapter->stat_miss);
+
+ if (ZFCP_STATUS_READS_RECOM <= atomic_read(&adapter->stat_miss)) {
+ zfcp_erp_adapter_reopen(adapter, 0, 103, NULL);
+ return 1;
+ }
+ return 0;
+}
+
+static void _zfcp_status_read_scheduler(struct work_struct *work)
+{
+ zfcp_status_read_refill(container_of(work, struct zfcp_adapter,
+ stat_work));
+}
+
/*
* Enqueues an adapter at the end of the adapter list in the driver data.
* All adapter internal structures are set up.
@@ -1055,6 +1084,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
/* initialize lock of associated request queue */
rwlock_init(&adapter->request_queue.queue_lock);
+ INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
/* mark adapter unusable as long as sysfs registration is not complete */
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
@@ -1066,8 +1096,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
adapter->generic_services.parent = &adapter->ccw_device->dev;
adapter->generic_services.release = zfcp_dummy_release;
- snprintf(adapter->generic_services.bus_id, BUS_ID_SIZE,
- "generic_services");
+ dev_set_name(&adapter->generic_services, "generic_services");
if (device_register(&adapter->generic_services))
goto generic_services_failed;
@@ -1115,6 +1144,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
int retval = 0;
unsigned long flags;
+ cancel_work_sync(&adapter->stat_work);
zfcp_adapter_scsi_unregister(adapter);
device_unregister(&adapter->generic_services);
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
@@ -1218,24 +1248,19 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
if (status & ZFCP_STATUS_PORT_WKA) {
switch (d_id) {
case ZFCP_DID_DIRECTORY_SERVICE:
- snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,
- "directory");
+ dev_set_name(&port->sysfs_device, "directory");
break;
case ZFCP_DID_MANAGEMENT_SERVICE:
- snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,
- "management");
+ dev_set_name(&port->sysfs_device, "management");
break;
case ZFCP_DID_KEY_DISTRIBUTION_SERVICE:
- snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,
- "key_distribution");
+ dev_set_name(&port->sysfs_device, "key_distribution");
break;
case ZFCP_DID_ALIAS_SERVICE:
- snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,
- "alias");
+ dev_set_name(&port->sysfs_device, "alias");
break;
case ZFCP_DID_TIME_SERVICE:
- snprintf(port->sysfs_device.bus_id, BUS_ID_SIZE,
- "time");
+ dev_set_name(&port->sysfs_device, "time");
break;
default:
kfree(port);
@@ -1244,8 +1269,7 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
port->d_id = d_id;
port->sysfs_device.parent = &adapter->generic_services;
} else {
- snprintf(port->sysfs_device.bus_id,
- BUS_ID_SIZE, "0x%016llx", wwpn);
+ dev_set_name(&port->sysfs_device, "0x%016llx", wwpn);
port->sysfs_device.parent = &adapter->ccw_device->dev;
}
port->sysfs_device.release = zfcp_sysfs_port_release;
@@ -1502,19 +1526,16 @@ zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool)
{
struct zfcp_gid_pn_data *data;
- if (pool != NULL) {
+ if (pool)
data = mempool_alloc(pool, GFP_ATOMIC);
- if (likely(data != NULL)) {
- data->ct.pool = pool;
- }
- } else {
+ else
data = kmem_cache_alloc(zfcp_data.gid_pn_cache, GFP_ATOMIC);
- }
if (NULL == data)
return -ENOMEM;
memset(data, 0, sizeof(*data));
+ data->ct.pool = pool;
sg_init_table(&data->req , 1);
sg_init_table(&data->resp , 1);
data->ct.req = &data->req;