diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 63 |
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; |