]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/qla2xxx/qla_mid.c
[ARM] Merge most of the PXA work for initial merge
[linux-2.6-omap-h63xx.git] / drivers / scsi / qla2xxx / qla_mid.c
index 821ee74aadc675ed4a7f3f5a1157000d76079413..62a3ad6e8ecb0d1a0c457e3617019b39298344ba 100644 (file)
@@ -1,20 +1,8 @@
 /*
- *                  QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.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 the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
+ * See LICENSE.qla2xxx for copyright and licensing details.
  */
 #include "qla_def.h"
 
@@ -28,8 +16,6 @@
 #include <scsi/scsicam.h>
 #include <linux/delay.h>
 
-void qla2x00_vp_stop_timer(scsi_qla_host_t *);
-
 void
 qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
 {
@@ -39,28 +25,27 @@ qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
        }
 }
 
-uint32_t
+static uint32_t
 qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
 {
        uint32_t vp_id;
        scsi_qla_host_t *ha = vha->parent;
 
        /* Find an empty slot and assign an vp_id */
-       down(&ha->vport_sem);
-       vp_id = find_first_zero_bit((unsigned long *)ha->vp_idx_map,
-                               MAX_MULTI_ID_FABRIC);
-       if (vp_id > MAX_MULTI_ID_FABRIC) {
-               DEBUG15(printk ("vp_id %d is bigger than MAX_MULTI_ID_FABRID\n",
-                   vp_id));
-               up(&ha->vport_sem);
+       mutex_lock(&ha->vport_lock);
+       vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1);
+       if (vp_id > ha->max_npiv_vports) {
+               DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n",
+                   vp_id, ha->max_npiv_vports));
+               mutex_unlock(&ha->vport_lock);
                return vp_id;
        }
 
-       set_bit(vp_id, (unsigned long *)ha->vp_idx_map);
+       set_bit(vp_id, ha->vp_idx_map);
        ha->num_vhosts++;
        vha->vp_idx = vp_id;
        list_add_tail(&vha->vp_list, &ha->vp_list);
-       up(&ha->vport_sem);
+       mutex_unlock(&ha->vport_lock);
        return vp_id;
 }
 
@@ -70,15 +55,15 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
        uint16_t vp_id;
        scsi_qla_host_t *ha = vha->parent;
 
-       down(&ha->vport_sem);
+       mutex_lock(&ha->vport_lock);
        vp_id = vha->vp_idx;
        ha->num_vhosts--;
-       clear_bit(vp_id, (unsigned long *)ha->vp_idx_map);
+       clear_bit(vp_id, ha->vp_idx_map);
        list_del(&vha->vp_list);
-       up(&ha->vport_sem);
+       mutex_unlock(&ha->vport_lock);
 }
 
-scsi_qla_host_t *
+static scsi_qla_host_t *
 qla24xx_find_vhost_by_name(scsi_qla_host_t *ha, uint8_t *port_name)
 {
        scsi_qla_host_t *vha;
@@ -160,9 +145,9 @@ qla24xx_enable_vp(scsi_qla_host_t *vha)
        }
 
        /* Initialize the new vport unless it is a persistent port */
-       down(&ha->vport_sem);
+       mutex_lock(&ha->vport_lock);
        ret = qla24xx_modify_vp_config(vha);
-       up(&ha->vport_sem);
+       mutex_unlock(&ha->vport_lock);
 
        if (ret != QLA_SUCCESS) {
                fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
@@ -216,11 +201,7 @@ qla2x00_alert_all_vps(scsi_qla_host_t *ha, uint16_t *mb)
        if (ha->parent)
                return;
 
-       i = find_next_bit((unsigned long *)ha->vp_idx_map,
-           MAX_MULTI_ID_FABRIC + 1, 1);
-       for (;i <= MAX_MULTI_ID_FABRIC;
-           i = find_next_bit((unsigned long *)ha->vp_idx_map,
-           MAX_MULTI_ID_FABRIC + 1, i + 1)) {
+       for_each_mapped_vp_idx(ha, i) {
                vp_idx_matched = 0;
 
                list_for_each_entry(vha, &ha->vp_list, vp_list) {
@@ -270,12 +251,20 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
        qla24xx_enable_vp(vha);
 }
 
-int
+static int
 qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
 {
+       scsi_qla_host_t *ha = vha->parent;
+
        if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
                /* VP acquired. complete port configuration */
-               qla24xx_configure_vp(vha);
+               if (atomic_read(&ha->loop_state) == LOOP_READY) {
+                       qla24xx_configure_vp(vha);
+               } else {
+                       set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
+                       set_bit(VP_DPC_NEEDED, &ha->dpc_flags);
+               }
+
                return 0;
        }
 
@@ -311,11 +300,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *ha)
 
        clear_bit(VP_DPC_NEEDED, &ha->dpc_flags);
 
-       i = find_next_bit((unsigned long *)ha->vp_idx_map,
-           MAX_MULTI_ID_FABRIC + 1, 1);
-       for (;i <= MAX_MULTI_ID_FABRIC;
-           i = find_next_bit((unsigned long *)ha->vp_idx_map,
-           MAX_MULTI_ID_FABRIC + 1, i + 1)) {
+       for_each_mapped_vp_idx(ha, i) {
                vp_idx_matched = 0;
 
                list_for_each_entry(vha, &ha->vp_list, vp_list) {
@@ -350,15 +335,17 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport)
 
        /* Check up unique WWPN */
        u64_to_wwn(fc_vport->port_name, port_name);
+       if (!memcmp(port_name, ha->port_name, WWN_SIZE))
+               return VPCERR_BAD_WWN;
        vha = qla24xx_find_vhost_by_name(ha, port_name);
        if (vha)
                return VPCERR_BAD_WWN;
 
        /* Check up max-npiv-supports */
        if (ha->num_vhosts > ha->max_npiv_vports) {
-               DEBUG15(printk("scsi(%ld): num_vhosts %d is bigger than "
-                   "max_npv_vports %d.\n", ha->host_no,
-                   (uint16_t) ha->num_vhosts, (int) ha->max_npiv_vports));
+               DEBUG15(printk("scsi(%ld): num_vhosts %ud is bigger than "
+                   "max_npv_vports %ud.\n", ha->host_no,
+                   ha->num_vhosts, ha->max_npiv_vports));
                return VPCERR_UNSUPPORTED;
        }
        return 0;
@@ -412,12 +399,14 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
        }
        vha->mgmt_svr_loop_id = 10 + vha->vp_idx;
 
-       init_MUTEX(&vha->mbx_cmd_sem);
-       init_MUTEX_LOCKED(&vha->mbx_intr_sem);
+       init_completion(&vha->mbx_cmd_comp);
+       complete(&vha->mbx_cmd_comp);
+       init_completion(&vha->mbx_intr_comp);
 
        INIT_LIST_HEAD(&vha->list);
        INIT_LIST_HEAD(&vha->fcports);
        INIT_LIST_HEAD(&vha->vp_fcports);
+       INIT_LIST_HEAD(&vha->work_list);
 
        vha->dpc_flags = 0L;
        set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
@@ -449,10 +438,10 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
        vha->flags.init_done = 1;
        num_hosts++;
 
-       down(&ha->vport_sem);
-       set_bit(vha->vp_idx, (unsigned long *)ha->vp_idx_map);
+       mutex_lock(&ha->vport_lock);
+       set_bit(vha->vp_idx, ha->vp_idx_map);
        ha->cur_vport_count++;
-       up(&ha->vport_sem);
+       mutex_unlock(&ha->vport_lock);
 
        return vha;