/*
- * This file is part of the zfcp device driver for
- * FCP adapters for IBM System z9 and zSeries.
*
- * (C) Copyright IBM Corp. 2002, 2006
+ * linux/drivers/s390/scsi/zfcp_aux.c
+ *
+ * FCP adapter driver for IBM eServer zSeries
+ *
+ * (C) Copyright IBM Corp. 2002, 2004
+ *
+ * Author(s): Martin Peschke <mpeschke@de.ibm.com>
+ * Raimund Schroeder <raimund.schroeder@de.ibm.com>
+ * Aron Zeh
+ * Wolfgang Taphorn
+ * Stefan Bader <stefan.bader@de.ibm.com>
+ * Heiko Carstens <heiko.carstens@de.ibm.com>
+ * Andreas Herrmann <aherrman@de.ibm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/*
- * Driver authors:
- * Martin Peschke (originator of the driver)
- * Raimund Schroeder
- * Aron Zeh
- * Wolfgang Taphorn
- * Stefan Bader
- * Heiko Carstens (kernel 2.6 port of the driver)
- * Andreas Herrmann
- * Maxim Shchetynin
- * Volker Sameske
- * Ralph Wuerthner
- */
-
#include "zfcp_ext.h"
/* accumulated log level (module parameter) */
/* declare driver module init/cleanup functions */
module_init(zfcp_module_init);
-MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com");
+MODULE_AUTHOR("Heiko Carstens <heiko.carstens@de.ibm.com>, "
+ "Andreas Herrman <aherrman@de.ibm.com>, "
+ "Martin Peschke <mpeschke@de.ibm.com>, "
+ "Raimund Schroeder <raimund.schroeder@de.ibm.com>, "
+ "Wolfgang Taphorn <taphorn@de.ibm.com>, "
+ "Aron Zeh <arzeh@de.ibm.com>, "
+ "IBM Deutschland Entwicklung GmbH");
MODULE_DESCRIPTION
- ("FCP (SCSI over Fibre Channel) HBA driver for IBM System z9 and zSeries");
+ ("FCP (SCSI over Fibre Channel) HBA driver for IBM eServer zSeries");
MODULE_LICENSE("GPL");
module_param(device, charp, 0400);
printk("\n");
}
-
-/****************************************************************/
-/****** Functions to handle the request ID hash table ********/
-/****************************************************************/
-
-#define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF
-
-static int zfcp_reqlist_init(struct zfcp_adapter *adapter)
-{
- int i;
-
- adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head),
- GFP_KERNEL);
-
- if (!adapter->req_list)
- return -ENOMEM;
-
- for (i=0; i<REQUEST_LIST_SIZE; i++)
- INIT_LIST_HEAD(&adapter->req_list[i]);
-
- return 0;
-}
-
-static void zfcp_reqlist_free(struct zfcp_adapter *adapter)
-{
- struct zfcp_fsf_req *request, *tmp;
- unsigned int i;
-
- for (i=0; i<REQUEST_LIST_SIZE; i++) {
- if (list_empty(&adapter->req_list[i]))
- continue;
-
- list_for_each_entry_safe(request, tmp,
- &adapter->req_list[i], list)
- list_del(&request->list);
- }
-
- kfree(adapter->req_list);
-}
-
-void zfcp_reqlist_add(struct zfcp_adapter *adapter,
- struct zfcp_fsf_req *fsf_req)
-{
- unsigned int i;
-
- i = fsf_req->req_id % REQUEST_LIST_SIZE;
- list_add_tail(&fsf_req->list, &adapter->req_list[i]);
-}
-
-void zfcp_reqlist_remove(struct zfcp_adapter *adapter, unsigned long req_id)
-{
- struct zfcp_fsf_req *request, *tmp;
- unsigned int i, counter;
- u64 dbg_tmp[2];
-
- i = req_id % REQUEST_LIST_SIZE;
- BUG_ON(list_empty(&adapter->req_list[i]));
-
- counter = 0;
- list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) {
- if (request->req_id == req_id) {
- dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
- dbg_tmp[1] = (u64) counter;
- debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
- list_del(&request->list);
- break;
- }
- counter++;
- }
-}
-
-struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter,
- unsigned long req_id)
-{
- struct zfcp_fsf_req *request, *tmp;
- unsigned int i;
-
- i = req_id % REQUEST_LIST_SIZE;
-
- list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list)
- if (request->req_id == req_id)
- return request;
-
- return NULL;
-}
-
-int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
-{
- unsigned int i;
-
- for (i=0; i<REQUEST_LIST_SIZE; i++)
- if (!list_empty(&adapter->req_list[i]))
- return 0;
-
- return 1;
-}
-
-#undef ZFCP_LOG_AREA
-
/****************************************************************/
/************** Uncategorised Functions *************************/
/****************************************************************/
goto out;
}
- sg_list = kzalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL);
+ sg_list = kmalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL);
if (sg_list == NULL) {
retval = -ENOMEM;
goto out;
}
+ memset(sg_list, 0, sizeof(*sg_list));
if (command != ZFCP_CFDC_IOC) {
ZFCP_LOG_INFO("IOC request code 0x%x invalid\n", command);
sg_list->count = size >> PAGE_SHIFT;
if (size & ~PAGE_MASK)
sg_list->count++;
- sg_list->sg = kcalloc(sg_list->count, sizeof(struct scatterlist),
+ sg_list->sg = kmalloc(sg_list->count * sizeof(struct scatterlist),
GFP_KERNEL);
if (sg_list->sg == NULL) {
sg_list->count = 0;
retval = -ENOMEM;
goto out;
}
+ memset(sg_list->sg, 0, sg_list->count * sizeof(struct scatterlist));
for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) {
sg->length = min(size, PAGE_SIZE);
zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
{
struct zfcp_unit *unit, *tmp_unit;
- unsigned int scsi_lun;
+ scsi_lun_t scsi_lun;
int found;
/*
if (unit)
return NULL;
- unit = kzalloc(sizeof (struct zfcp_unit), GFP_KERNEL);
+ unit = kmalloc(sizeof (struct zfcp_unit), GFP_KERNEL);
if (!unit)
return NULL;
+ memset(unit, 0, sizeof (struct zfcp_unit));
/* initialise reference count stuff */
atomic_set(&unit->refcount, 0);
device_unregister(&unit->sysfs_device);
}
+static void *
+zfcp_mempool_alloc(gfp_t gfp_mask, void *size)
+{
+ return kmalloc((size_t) size, gfp_mask);
+}
+
+static void
+zfcp_mempool_free(void *element, void *size)
+{
+ kfree(element);
+}
+
/*
* Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI
* commands.
zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
{
adapter->pool.fsf_req_erp =
- mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ERP_NR,
- sizeof(struct zfcp_fsf_req_pool_element));
- if (!adapter->pool.fsf_req_erp)
+ mempool_create(ZFCP_POOL_FSF_REQ_ERP_NR,
+ zfcp_mempool_alloc, zfcp_mempool_free, (void *)
+ sizeof(struct zfcp_fsf_req_pool_element));
+
+ if (NULL == adapter->pool.fsf_req_erp)
return -ENOMEM;
adapter->pool.fsf_req_scsi =
- mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_SCSI_NR,
- sizeof(struct zfcp_fsf_req_pool_element));
- if (!adapter->pool.fsf_req_scsi)
+ mempool_create(ZFCP_POOL_FSF_REQ_SCSI_NR,
+ zfcp_mempool_alloc, zfcp_mempool_free, (void *)
+ sizeof(struct zfcp_fsf_req_pool_element));
+
+ if (NULL == adapter->pool.fsf_req_scsi)
return -ENOMEM;
adapter->pool.fsf_req_abort =
- mempool_create_kmalloc_pool(ZFCP_POOL_FSF_REQ_ABORT_NR,
- sizeof(struct zfcp_fsf_req_pool_element));
- if (!adapter->pool.fsf_req_abort)
+ mempool_create(ZFCP_POOL_FSF_REQ_ABORT_NR,
+ zfcp_mempool_alloc, zfcp_mempool_free, (void *)
+ sizeof(struct zfcp_fsf_req_pool_element));
+
+ if (NULL == adapter->pool.fsf_req_abort)
return -ENOMEM;
adapter->pool.fsf_req_status_read =
- mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR,
- sizeof(struct zfcp_fsf_req));
- if (!adapter->pool.fsf_req_status_read)
+ mempool_create(ZFCP_POOL_STATUS_READ_NR,
+ zfcp_mempool_alloc, zfcp_mempool_free,
+ (void *) sizeof(struct zfcp_fsf_req));
+
+ if (NULL == adapter->pool.fsf_req_status_read)
return -ENOMEM;
adapter->pool.data_status_read =
- mempool_create_kmalloc_pool(ZFCP_POOL_STATUS_READ_NR,
- sizeof(struct fsf_status_read_buffer));
- if (!adapter->pool.data_status_read)
+ mempool_create(ZFCP_POOL_STATUS_READ_NR,
+ zfcp_mempool_alloc, zfcp_mempool_free,
+ (void *) sizeof(struct fsf_status_read_buffer));
+
+ if (NULL == adapter->pool.data_status_read)
return -ENOMEM;
adapter->pool.data_gid_pn =
- mempool_create_kmalloc_pool(ZFCP_POOL_DATA_GID_PN_NR,
- sizeof(struct zfcp_gid_pn_data));
- if (!adapter->pool.data_gid_pn)
+ mempool_create(ZFCP_POOL_DATA_GID_PN_NR,
+ zfcp_mempool_alloc, zfcp_mempool_free, (void *)
+ sizeof(struct zfcp_gid_pn_data));
+
+ if (NULL == adapter->pool.data_gid_pn)
return -ENOMEM;
return 0;
*/
/* try to allocate new adapter data structure (zeroed) */
- adapter = kzalloc(sizeof (struct zfcp_adapter), GFP_KERNEL);
+ adapter = kmalloc(sizeof (struct zfcp_adapter), GFP_KERNEL);
if (!adapter) {
ZFCP_LOG_INFO("error: allocation of base adapter "
"structure failed\n");
goto out;
}
+ memset(adapter, 0, sizeof (struct zfcp_adapter));
ccw_device->handler = NULL;
INIT_LIST_HEAD(&adapter->port_remove_lh);
/* initialize list of fsf requests */
- spin_lock_init(&adapter->req_list_lock);
- retval = zfcp_reqlist_init(adapter);
- if (retval) {
- ZFCP_LOG_INFO("request list initialization failed\n");
- goto failed_low_mem_buffers;
- }
+ spin_lock_init(&adapter->fsf_req_list_lock);
+ INIT_LIST_HEAD(&adapter->fsf_req_list_head);
/* initialize debug locks */
/* intitialise SCSI ER timer */
init_timer(&adapter->scsi_er_timer);
+ /* set FC service class used per default */
+ adapter->fc_service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;
+
+ sprintf(adapter->name, "%s", zfcp_get_busid_by_adapter(adapter));
+ ASCEBC(adapter->name, strlen(adapter->name));
+
/* mark adapter unusable as long as sysfs registration is not complete */
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
* !0 - struct zfcp_adapter data structure could not be removed
* (e.g. still used)
* locks: adapter list write lock is assumed to be held by caller
+ * adapter->fsf_req_list_lock is taken and released within this
+ * function and must not be held on entry
*/
void
zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
/* sanity check: no pending FSF requests */
- spin_lock_irqsave(&adapter->req_list_lock, flags);
- retval = zfcp_reqlist_isempty(adapter);
- spin_unlock_irqrestore(&adapter->req_list_lock, flags);
- if (!retval) {
+ spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+ retval = !list_empty(&adapter->fsf_req_list_head);
+ spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+ if (retval) {
ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, "
"%i requests outstanding\n",
zfcp_get_busid_by_adapter(adapter), adapter,
- atomic_read(&adapter->reqs_active));
+ atomic_read(&adapter->fsf_reqs_active));
retval = -EBUSY;
goto out;
}
zfcp_free_low_mem_buffers(adapter);
/* free memory of adapter data structure and queues */
zfcp_qdio_free_queues(adapter);
- zfcp_reqlist_free(adapter);
kfree(adapter->fc_stats);
kfree(adapter->stats_reset_data);
ZFCP_LOG_TRACE("freeing adapter structure\n");
return NULL;
}
- port = kzalloc(sizeof (struct zfcp_port), GFP_KERNEL);
+ port = kmalloc(sizeof (struct zfcp_port), GFP_KERNEL);
if (!port)
return NULL;
+ memset(port, 0, sizeof (struct zfcp_port));
/* initialise reference count stuff */
atomic_set(&port->refcount, 0);
zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
struct fsf_status_read_buffer *status_buffer)
{
- struct fsf_plogi *els_plogi;
+ logi *els_logi = (logi *) status_buffer->payload;
struct zfcp_port *port;
unsigned long flags;
- els_plogi = (struct fsf_plogi *) status_buffer->payload;
read_lock_irqsave(&zfcp_data.config_lock, flags);
list_for_each_entry(port, &adapter->port_list_head, list) {
- if (port->wwpn == (*(wwn_t *) &els_plogi->serv_param.wwpn))
+ if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn))
break;
}
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
- if (!port || (port->wwpn != (*(wwn_t *) &els_plogi->serv_param.wwpn))) {
+ if (!port || (port->wwpn != (*(wwn_t *) & els_logi->nport_wwn))) {
ZFCP_LOG_DEBUG("ignored incoming PLOGI for nonexisting port "
"with d_id 0x%08x on adapter %s\n",
status_buffer->d_id,
return ret;
}
-/**
- * zfcp_plogi_evaluate - evaluate PLOGI playload and copy important fields
- * into zfcp_port structure
- * @port: zfcp_port structure
- * @plogi: plogi payload
- */
-void
-zfcp_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi)
-{
- port->maxframe_size = plogi->serv_param.common_serv_param[7] |
- ((plogi->serv_param.common_serv_param[6] & 0x0F) << 8);
- if (plogi->serv_param.class1_serv_param[0] & 0x80)
- port->supported_classes |= FC_COS_CLASS1;
- if (plogi->serv_param.class2_serv_param[0] & 0x80)
- port->supported_classes |= FC_COS_CLASS2;
- if (plogi->serv_param.class3_serv_param[0] & 0x80)
- port->supported_classes |= FC_COS_CLASS3;
- if (plogi->serv_param.class4_serv_param[0] & 0x80)
- port->supported_classes |= FC_COS_CLASS4;
-}
-
#undef ZFCP_LOG_AREA